Типы данных, определяемые пользователем 

При разработке программ могут потребоваться типы данных, отличные от типов данных, встроенных в язык программирования С++. Введение новых типов данных преследует три цели:

  • ограничить множество значений существующего интегрального типа  данных (используются перечисления) ;

  • определить тип, который описывает данные, имеющие сложную структуру (структуры и объединения);

  • переименовать тип данных, чтобы придать ему более осмысленное имя (используется определение typedef).

Замечание:  В языке программирования С++ типы данных могут объявляется в любом месте программы.

Перечисления

Перечислением называется тип данных, который включает набор именованных целочисленных констант. Элементы перечисления называются перечислимыми константами.

Синтаксис: еnum  имя_перечисления {список значений};

еnum – ключевое слово;

имя_перечисления  служит для именования типа перечисления;

список значений перечисляет именованные целочисленные константы, принадлежащие перечислению.

Примеры:

enum boolean {false, true};

enum otvet {no,yes} ;

enum color {black, red, blue, green, white};

При объявлении перечисления его элементы могут инициализироваться.

enum color {black=2, red=3, blue=5, green=6, white=8};

По умолчанию перечислимым константам присваиваются  последовательные значения, начиная с нуля.

Например, enum color {black, red, blue, green, white};

Это значит, что black = 0, red = 1, blue = 2, green = 3, white = 3.

Если начиная с некоторой перечислимой константы, инициализация прекращается, то следующей перечислимой константе присваивается значение на единицу большее, чем значение предыдущей перечислимой константы.

Например, enum color {black, red=3, blue, green=7, white}; 

Перечислимые константы имеют значения: black = 0, blue = 4, white = 8.

Переменную типа «перечисление» можно объявить следующим образом: color d;  //d – переменная типа color

Объявление типа перечисления и переменной, которая имеет этот тип, может быть объединено в одну инструкцию.

Например, enum color {black, red, blue, green, white} d;

Переменной типа перечисления можно присваивать только значения, принадлежащие её типу. Эти значения могут присваиваться переменной, используя только имена перечислимых констант.

Например, color d;  d = black;  или d =red;

Целочисленным переменным можно присваивать значения перечислимых переменных.

Например, int t = red; (red = 0).

Особенность: перечисляемые идентификаторы должны отличатся друг от друга, а присваиваемые им значения могут совпадать.

enum color {black=2, red=3, blue=3, green=6, white=6};

Ограничения:

  • данные перечислимого типа нельзя использовать с командами ввода-вывода;

  • с данными перечислимого типа нельзя выполнять арифметические операции, но можно сравнивать и присваивать.

Структуры

Структура – это объединено в единое целое множество поименованных элементов разных типов под одним именем. Перечисляемые в структуре переменные называются полями.

Синтаксис: struct  имя_структуры {список полей };

struct – ключевое слово;

имя_структуры  для именования структурного типа;

{список_полей}={тип1 имя_поля1; тип2 имя_поля2;…; типn имя_поляn;}

Примеры:

struct employee {char fio[20];

                 char dol[15];

                 long zpl;

                };

Описание переменных структурного типа:

  • Определив структурный тип в программе можно его использовать для объявления переменных данного типа. Например, struct point {double x; double v;}; point p1, p2, p3;

  • Переменные структурного типа могут объявляется и при определении самой структуры. Например, struct point {double x; double v;} p1, p2; 

  • Структурную переменную при ее определении можно инициализировать. Значения переменных структуры перечисляют в {} в порядке описания. Например, point p1={1.0, -8.3};

employee={“Иванов С.Ю.”,”инженер”, 249, 3000};

  • Доступ к полям структуры выполняется с помощью операции точка (.) переменная.элемент(поле)

Например, p1.x=1.0;  p1.y=-8.3;

employee d1;

d1.fio=”Иванов С.Ю.”;

d1.dol=”инженер”;

d1.tab=249;

d1.zpl=3000;

  • Для переменных одного и того же  структурного типа определена операция присваивания. При этом происходит поэлементное копирование. Например,

p1.x = 5.6

p2.x = p1.x;  p2.x = 5.6;

  • Допускается использование массивов – структур.

  • Поля структуры располагаются в памяти последовательно друг за другом.

Объединение

Объединением называется область памяти, используемая для хранения данных разных типов.

Синтаксис: union имя_объединения  {список полей;};

union – ключевое слово;

имя_объединения  для именования типа объединения;

{список_полей}={тип1 имя_поля1; тип2 имя_поля2;…; типn имя_поля n;}.

Пример: union num {int i; char ch; long h;};

Описание переменных типа объединение:

  • Переменная типа объединения объявляется следующим образом: num d;

  • Либо таким образом:    union num {int i; char ch; long h;} d;

  • Для доступа к полям объединения используется оператор точка. Например, d.i = 12, d.h = 35000;

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

Переименование типов

Одна из  возможностей создания пользовательских типов – это переименование типа.

Синтаксис:    typedef  имя_старого_типа  имя_нового_типа

Примеры:  typedef int integer

           typedef float real

Переименование типов используется для:

  • создания более коротких альтернативных имен;

  • определения имен типов, которые более привычные пользователю;

  • определения нового типа, который лучше описывает, как используется этот тип;

  • облегчения переносимости программ.

 Пример структуры (Решение задачи можно посмотреть, скачав файл "Задача-15"):

Дана структура с именем Student, содержащая поля: имя студента, пол, рост. Определить имя самого высокого студента. Использовать функцию для ввода данных.

#include<iostream.h>
#include<conio.h>
#define n 5
struct Student {char name[40];
        char pol[1];
        float rost;};
void vvod (Student st1[n], int m)
{cout<<"Vvedite imya"<<'\n'; 
 cin>>st1[m].name;
 cout<<"Vvedite pol"<<'\n';
 cin>>st1[m].pol;
 cout<<"Vvedite rost"<<'\n';
 cin>>st1[m].rost;
}

void main()
{clrscr();
 Student st[n]; int i, max, ind;
 cout<<"Vvedite dannie o studentah"<<'\n';
 vvod(st,0);
 max=st[0].rost;
 ind=0;
 for (i=1; i<n; i++)
     {vvod (st, i);
      if (max<st[i].rost) {max=st[i].rost;
                           ind=i;
                          }
     }
 cout<<"Samiy visokiy student "<<st[ind].name;
 cout<<" Ego rost= "<<max<<'\n';
}

 Пример объединения (Решение задачи можно посмотреть, скачав файл "Задача-16"):

Дано значение в метрах. Получить значение в сантиметрах, миллиметрах, километрах. Использовать объединение.

#include<iostream.h>
#include<conio.h>
#include<iomanip.h>
void main()
{union rast {float km, m, sm, mm;};//vse peremenie zanimayut odnu pamyat
 rast d;
 cout.setf(ios::fixed);//vivod veshestvennih chisel c tochkoy
 cout<<"\nVvedite znechenie v metrah"<<'\n';
 cin>>d.m;

 d.km=d.m/1000;
 cout<<"Velichina v km "<<d.km<<'\n';
 d.sm=100000*d.km;

 cout<<"Velichina v sm ";
 cout.precision(1);cout<<d.sm<<'\n';
 d.mm=10*d.sm;

 cout<<"Velichina v mm ";
 cout.precision(1);cout<<d.mm<<'\n';
 getch();
}

Пример объединения (Решение задачи можно посмотреть, скачав файл "Задача-17"):

Используя перечисления, создайте программу для выполнения операций с двумя числами. Операция(+,-,*,/) и сами числа вводятся пользователем.

#include<iostream.h>
#include<conio.h>
enum mathError {noEr, BadOp, divZ};
void f (mathError err)
{switch (err)
 {case noEr : cout<<"Net oshibok"; break;
  case BadOp : cout<<"Oshibka operacii"; break;
  case divZ : cout<<"Delenie na 0!!!"; break;
 }
}
main()
{int x, y, z;
 char op;
 mathError n=noEr;
 cout<<"\nVvedite 2 chisla i operaciu dlya nih"<<endl;
 cin>>x>>op>>y;
 switch(op)
 {case '+' : z=x+y; break;
  case '-' : z=x-y; break;
  case '*' : z=x*y; break;
  case '/' : if (y!=0) {z=x/y; break;}
        else {n=divZ;break;}
  default : n= BadOp;
 }
if (n==noEr) cout<<z;
  else f(n);
getch();
return 0;
}

Среда, 08.05.2024, 12:18
Приветствую Вас Гость