Форум программистов, компьютерный форум CyberForum.ru

Задание с использованием Объединения - C++

Восстановить пароль Регистрация
 
rakdimka
0 / 0 / 0
Регистрация: 26.11.2012
Сообщений: 8
26.11.2012, 23:20     Задание с использованием Объединения #1
Собственно, типичная курсовая по С++, 2-й курс, задание изложу ниже. Есть несколько вопросов к людям с соображалкой и знанием С++.

Написать программу, в которой объединение используется для хранения информации об одной из геометрических фигур: трапеции или треугольнике. Программа вычисляет площадь данных фигур и выводит результат. Предусмотреть меню. Результаты работы программы записать в файл.

Итак. Вопрос. Насчет кода в общем-то проблем думаю у меня не возникнет. Вопрос только в использовании объединения. Конечно если бы писать все это через структуру, то и особых знаний не нужно было бы. А так, скажите пожалуйста, лучше всего использовать вот такой способ реализации как приведу ниже?

C++
1
2
3
4
union square {
   struct treugolnik {описание переменных};
   struct trapecia {описание переменных};
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ps10n1ck
 Аватар для ps10n1ck
53 / 47 / 2
Регистрация: 10.11.2010
Сообщений: 132
26.11.2012, 23:47     Задание с использованием Объединения #2
вместо этого:
C++
1
2
3
4
union square {
   struct treugolnik {описание переменных};
   struct trapecia {описание переменных};
}
лучше:
C++
1
2
3
4
5
6
7
struct treugolnik {описание переменных};
struct trapecia {описание переменных};
 
union square {
   treugolnik *pTreugolnik;
   trapecia *pTrapecia; 
}
т.к. если у вас описания структур разные будут (по размеру), то в union'e будет выделяться лишняя память:
к примеру sizeof(treugolnik)=32byte, а sizeof(trapecia)=64byte, то при вашем описании union - sizeof(square)=64byte;
а в моем случае, в union square будет просто храниться указатель, который указывает на необходимую структуру, в этом случае sizeof(square)=sizeof(указателя)
rakdimka
0 / 0 / 0
Регистрация: 26.11.2012
Сообщений: 8
27.11.2012, 12:10  [ТС]     Задание с использованием Объединения #3
Спасибо, главное структура программы в моей головушке образовалась. А с указателями и их использованием разберусь

Добавлено через 12 часов 18 минут
Приведу кусок кода. Что-то сделал не так с объединением или структурами? И главный вопрос... В конце идет вычисление площади. Если брать типы для переменных скажем Int, а для площади Float, то считает неверно... Если все Float, то вообще билиберда. ХЕЛП!)

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <stdio.h>
#include <math.h>
#include <conio.h>
#include <clocale>
 
using namespace std;
 
struct Triangle
{
    unsigned int uiSide1,uiSide2,uiAngle;
    float fSquare;
} a;
struct Trapeze
{
    unsigned int uiBase1,uiBase2,uiHeight;
    float fSquare;
} b;
 
union uFigure
{
    Triangle *ptrTriangle;
    Trapeze *ptrTrapeze;
} c;
 
int main()
{
setlocale(LC_ALL,"");
    int iMenu=0;
 
    printf("Добро пожаловать в программу figure\n");
    printf("Данная программа вычисляет площадь выбранной вами фигуры\n");
 
    printf("Выберите фигуру, площадь которой вы хотите вычислить:\n");
    printf("1. ТРАПЕЦИЯ\n");
    printf("2. ТРЕУГОЛЬНИК\n");
    printf("3. Выход из программы\n");
    scanf("%i",&iMenu);
 
    switch(iMenu)
    {
        case 1: 
            c.ptrTrapeze=&b;
 
            printf("Введите первое основание: ");
            scanf("%i",&(*c.ptrTrapeze).uiBase1);
            printf("Введите второе основание: ");
            scanf("%i",&(*c.ptrTrapeze).uiBase2);
            printf("Введите высоту: ");
            scanf("%i",&(*c.ptrTrapeze).uiHeight);
            (*c.ptrTrapeze).fSquare=((*c.ptrTrapeze).uiBase1+(*c.ptrTrapeze).uiBase2)/2*(*c.ptrTrapeze).uiHeight;
        
            printf("Основание А     Основание B    Высота H    Площадь(S=(A+B)/2*h)\n");
            printf("%7i   %10i    %10i   %15d", (*c.ptrTrapeze).uiBase1,(*c.ptrTrapeze).uiBase2,(*c.ptrTrapeze).uiHeight,(*c.ptrTrapeze).fSquare);
ps10n1ck
 Аватар для ps10n1ck
53 / 47 / 2
Регистрация: 10.11.2010
Сообщений: 132
27.11.2012, 16:07     Задание с использованием Объединения #4
т.к. ваши данные и для трапеции и для треугольника имеют одинаковый размер, то можно избежать указателей:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <iostream>
 
using std::cout;
using std::cin;
using std::endl;
 
typedef unsigned int uint;
#define M_PI       3.14159265358979323846
 
union SQUARE {
  struct TRIANGLE {
    uint nSideA;
    uint nSideB;
    uint nAngle;
    float fSquare;
  } Triangle;
 
  struct TRAPEZIUM {
    uint nBaseA;
    uint nBaseB;
    uint nHeight;
    float fSquare;
  } Trapezium;
} Square;
 
int main(){
  setlocale(LC_ALL, "rus");
  uint nMenu = 0;
  
  cout << "Вас приветствует программа для расчета площади фигур." << endl;
  cout << "Выберите фигуру для расчета площади: " << endl;
  cout << "1. Треугольник" << endl;
  cout << "2. Трапеция" << endl;
  cout << "0. Выйти" << endl;
  cout << "Ваш выбор: ";
  while(cin >> nMenu && nMenu != 0){
    switch(nMenu){
      case 1:
        cout << endl << "Вы выбрали [Треугольник]" << endl;
        cout << "Введите данные для расчета площади:" << endl;
        cout << "Сторона А: ";
        cin >> Square.Triangle.nSideA;
        cout << "Сторона B: ";
        cin >> Square.Triangle.nSideB;
        cout << "Угол между сторонами: ";
        cin >> Square.Triangle.nAngle;
        Square.Triangle.fSquare = 0.5f * Square.Triangle.nSideA * Square.Triangle.nSideB * sin(float(Square.Triangle.nAngle * M_PI / 180.0f)); 
        cout << "Площадь треугольника равна: " << Square.Triangle.fSquare << endl << endl;
        break;
 
      case 2:
        cout << endl << "Вы выбрали [Трапеция]" << endl;
        cout << "Введите данные для расчета площади:" << endl;
        cout << "Основание А: ";
        cin >> Square.Trapezium.nBaseA;
        cout << "Основание B: ";
        cin >> Square.Trapezium.nBaseB;
        cout << "Высота: ";
        cin >> Square.Trapezium.nHeight;
        Square.Trapezium.fSquare = 0.5f * (Square.Trapezium.nBaseA + Square.Trapezium.nBaseB) * Square.Trapezium.nHeight; 
        cout << "Площадь трапеции равна: " << Square.Trapezium.fSquare << endl << endl;
        break;
 
      default:
        break;
    }
    cout << "Выберите фигуру для расчета площади: " << endl;
    cout << "1. Треугольник" << endl;
    cout << "2. Трапеция" << endl;
    cout << "0. Выйти" << endl;
    cout << "Ваш выбор: ";
  }
 
return 0;
}
в этом случае структура SQUARE - будет занимать 16 байт (на 32битной арх.) но у вас есть возможность получить данные (стороны, угол или высоту) о последней фигуре.
можно уменьшить до 12 байт - (на 32битной арх.)
для этого необходимо немного изменить саму структуру:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
union SQUARE {
  struct TRIANGLE {
    uint nSideA;
    uint nSideB;
    uint nAngle;
  } Triangle;
 
  struct TRAPEZIUM {
    uint nBaseA;
    uint nBaseB;
    uint nHeight;
  } Trapezium;
 
    float fSquare;
} Square;
 
площадь можно тогда вычислять так:
Square.fSquare = ....
но в данном случае, как только вы посчитаете площадь, данные первого поля структуры TRIANGLE или TRAPEZIUM будут затерты.
union использует память под хранение одного поля - в вашем случае память выделится под самую большую переменную - структуру TRIANGLE или TRAPEZIUM - разницы нет.
А потом когда, вы посчитаете площадь, в выделенную память будет занесено значение fSquare (4байта), а остальные 8 байт будут содержать остатки от данных структуры (значения 2х последних полей структуры TRIANGLE или TRAPEZIUM).
rakdimka
0 / 0 / 0
Регистрация: 26.11.2012
Сообщений: 8
28.11.2012, 17:41  [ТС]     Задание с использованием Объединения #5
Ну огромнейшее спасибо за помощь Уж очень упростили задачу. Возьмусь за ошибки ввода и сохранение в файл

Добавлено через 19 часов 9 минут
Ну собственно окончательный вариант моего курсача таков. Если, конечно, без "проверки на дурака" примут. Теперь вот мучаюсь с блок-схемами через Edraw Max. Запись в делал в единичный файл, с последующей перезаписью поверх, имхо поленился, в спецификации не указано большего.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include <iostream>
 
using std::cout;
using std::cin;
using std::endl;
 
typedef unsigned int uint;
#define M_PI       3.14159265358979323846
 
union SQUARE {
  struct TRIANGLE {
    uint nSideA;
    uint nSideB;
    uint nAngle;
    float fSquare;
  } Triangle;
 
  struct TRAPEZIUM {
    uint nBaseA;
    uint nBaseB;
    uint nHeight;
    float fSquare;
  } Trapezium;
} Square;
 
int main()
{
  setlocale(LC_ALL, "rus");
  uint nMenu = 0;
  uint nFileWriting = 0; 
  
  cout << "Вас приветствует программа для расчета площади фигур." << endl;
  cout << "Выберите фигуру для расчета площади: " << endl;
  cout << "1. Треугольник" << endl;
  cout << "2. Трапеция" << endl;
  cout << "0. Выйти" << endl;
  cout << "Ваш выбор: ";
  while(cin >> nMenu && nMenu != 0)
  {
    switch(nMenu)
    {
      case 1:
        cout << endl << "Вы выбрали [Треугольник]" << endl;
        cout << "Введите данные для расчета площади:" << endl;
        cout << "Сторона А: ";
        cin >> Square.Triangle.nSideA;
        cout << "Сторона B: ";
        cin >> Square.Triangle.nSideB;
        cout << "Угол между сторонами: ";
        cin >> Square.Triangle.nAngle;
        Square.Triangle.fSquare = 0.5f * Square.Triangle.nSideA * Square.Triangle.nSideB * sin(float(Square.Triangle.nAngle * M_PI / 180.0f)); 
        cout << "Площадь треугольника равна: " << Square.Triangle.fSquare << endl << endl;
        cout<<"Хотите записать данные в файл?"<<endl;
        cout<<"1. Да "<<endl<<"2. Нет"<<endl;
        cin>>nFileWriting;
        if (nFileWriting==1)
        {
            FILE *file;
            char* file_name = "results.txt";
            file = fopen( file_name, "w" ); 
            fprintf(file," Сторона A: %i\n Сторона B: %i\n Угол между сторон: %i\n Площадь: %f\n", Square.Triangle.nSideA, Square.Triangle.nSideB, Square.Triangle.nAngle, Square.Triangle.fSquare);
            fclose( file );
            cout<<"Файл results.txt был перезаписан"<<endl<<endl;
        }
        
        break;
 
      case 2:
        cout << endl << "Вы выбрали [Трапеция]" << endl;
        cout << "Введите данные для расчета площади:" << endl;
        cout << "Основание А: ";
        cin >> Square.Trapezium.nBaseA;
        cout << "Основание B: ";
        cin >> Square.Trapezium.nBaseB;
        cout << "Высота: ";
        cin >> Square.Trapezium.nHeight;
        Square.Trapezium.fSquare = 0.5f * (Square.Trapezium.nBaseA + Square.Trapezium.nBaseB) * Square.Trapezium.nHeight; 
        cout << "Площадь трапеции равна: " << Square.Trapezium.fSquare << endl << endl;
        cout<<"Хотите записать данные в файл?"<<endl;
        cout<<"1. Да "<<endl<<"2. Нет"<<endl;
        cin>>nFileWriting;
        if (nFileWriting==1)
        {
            FILE *file;
            char* file_name = "results.txt";
            file = fopen( file_name, "w" ); 
            fprintf(file," Основание A: %i\n Основание B: %i\n Высота: %i\n Площадь: %f\n", Square.Trapezium.nBaseA, Square.Trapezium.nBaseB, Square.Trapezium.nHeight, Square.Trapezium.fSquare);
            fclose( file );
            cout<<"Файл results.txt был перезаписан"<<endl<<endl;
        }
        break;
 
      default:
        break;
    }
    cout << "Выберите фигуру для расчета площади: " << endl;
    cout << "1. Треугольник" << endl;
    cout << "2. Трапеция" << endl;
    cout << "0. Выйти" << endl;
    cout << "Ваш выбор: ";
  }
 
return 0;
}
Yandex
Объявления
28.11.2012, 17:41     Задание с использованием Объединения
Ответ Создать тему
Опции темы

Текущее время: 01:35. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru