Скачать презентацию ТИПЫ ДАННЫХ ОПРЕДЕЛЯЕМЫЕ ПРОГРАММИСТОМ СТРУКТУРЫ typedef Для Скачать презентацию ТИПЫ ДАННЫХ ОПРЕДЕЛЯЕМЫЕ ПРОГРАММИСТОМ СТРУКТУРЫ typedef Для

Лекция 8.ppt

  • Количество слайдов: 49

ТИПЫ ДАННЫХ, ОПРЕДЕЛЯЕМЫЕ ПРОГРАММИСТОМ. СТРУКТУРЫ ТИПЫ ДАННЫХ, ОПРЕДЕЛЯЕМЫЕ ПРОГРАММИСТОМ. СТРУКТУРЫ

typedef Для объявления имен новых типов данных используется ключевого слова typedef: typedef <имя_типа> <новое_имя>; typedef Для объявления имен новых типов данных используется ключевого слова typedef: typedef <имя_типа> <новое_имя>; Новый тип данных не создается, а определяется новое имя существующего типа typedef float balance; balance money; // это вещественная переменная типа balance, другими словами - типа float.

Структуры Структуры

Структура - это составной объект, в который входят элементы любых типов, за исключением функций. Структура - это составной объект, в который входят элементы любых типов, за исключением функций. Для удобства работы с этими данными они сгруппированы под одним именем. При разработке программ структуры помогают в организации хранения и обработке сложных данных, не разобщая их по различным объектам, а группируя в одном. Объекты, входящие в структуру, сами могут быть структурой, т. е. структуры могут быть вложенными.

Как и массив, структура представляет собой совокупность данных (полей), но отличается от него тем, Как и массив, структура представляет собой совокупность данных (полей), но отличается от него тем, что к ее элементам (компонентам) необходимо обращаться по имени и ее элементы могут быть различного типа. Структуры целесообразно использовать там, где необходимо объединить разнообразные данные, относящиеся к одному объекту.

Как и другие объекты в Си, структуры должны быть определены. Для определения структуры создается Как и другие объекты в Си, структуры должны быть определены. Для определения структуры создается некоторый тип, являющийся структурой, а затем, по мере необходимости, определяются переменные этого типа (типа структура). Объявление структуры осуществляется с помощью ключевого слова struct, за которым следует имя, называемое тегом (именем) структуры и списка элементов, заключенных в фигурные скобки.

Тег дает название структуре данного вида и в дальнейшем служит кратким обозначением той части Тег дает название структуре данного вида и в дальнейшем служит кратким обозначением той части описания структуры, которая заключена в фигурные скобки, то есть является спецификатором. struct adres { char name[30]; char street [40]; char city[20]; char state[3]; }; Объявление завершается точкой с запятой, поскольку объявление структуры - это оператор.

Имя структуры adres идентифицирует структуру данных и является спецификатором типа. На данный момент переменная Имя структуры adres идентифицирует структуру данных и является спецификатором типа. На данный момент переменная еще не создана! Определена только форма данных. Для объявления переменной, соответствующей данной структуре, следует написать: struct adres Adres. Info;

Когда объявлена структурная переменная, компилятор автоматически выделяет необходимый участок памяти для размещения всех ее Когда объявлена структурная переменная, компилятор автоматически выделяет необходимый участок памяти для размещения всех ее членов. char name[30]; char street [40]; char city[20]; char state[3]; Adres. Info

При объявлении структуры можно одновременно объявить несколько переменных: struct adres { char name[30]; char При объявлении структуры можно одновременно объявить несколько переменных: struct adres { char name[30]; char street[40]; char city[20]; char state[3]; } Adres. Info 1, Adres. Info 2, Adres. Info 3; Если необходима только одна структурная переменная: struct { char name[30]; char street[40]; char city[20]; char state[3]; } Adres. Info;

Не рекомендуется декларировать поле структуры указателем на объект переменной размерности. При декларации структурных переменных Не рекомендуется декларировать поле структуры указателем на объект переменной размерности. При декларации структурных переменных возможна их одновременная инициализация. struct adres { char name[30]; char street[40]; char city[20]; } Adres. Info = {“Ivanov I. I. ", “Kozlova”, “ Minsk" }; или adres Adres. Info = {"Ivanov I. I. ", “Kozlova”, “ Minsk" }; Если список инициализации короче, то оставшиеся поля заполняются « 0»

Доступ к компонентам структуры Доступ к компонентам структуры

а) с использованием операции принадлежности (. ) в виде: имя_переменной_структуры. ID_поля или (*указатель_структуры). ID_поля а) с использованием операции принадлежности (. ) в виде: имя_переменной_структуры. ID_поля или (*указатель_структуры). ID_поля такой способ доступа к элементам структуры работает только в том случае, когда структура не является указателем на структуру. б) при помощи операции косвенной адресации (->) в виде: указатель_структуры -> ID_поля или (&ID_структуры) ->ID_поля

date[1]. day=12; strcpy(att[10]. FIO, ”Ivanov I. I. ”); Доступ по указателю strcpy((per_ptr+10)->FIO, ” Ivanov date[1]. day=12; strcpy(att[10]. FIO, ”Ivanov I. I. ”); Доступ по указателю strcpy((per_ptr+10)->FIO, ” Ivanov I. I. ”); или strcpy((*(per_ptr+10))->FIO, ” Ivanov I. I. ”); att[i]. mark=6; (att+i)->mark=6; (*(att+i). mark=6;

Пример 1 #include <stdio. h> #include <conio. h> #include <locale. h> struct school { Пример 1 #include #include #include struct school { char FIO[100]; int math; int eng; int phys; char pov[20]; double aver; }; void main(){ school att[30]; char ch; setlocale(LC_CTYPE, "Russian"); int rec = 0; Объявление структуры Объявление массива структур

do { system( do { system("cls"); printf("студент №%dn", rec + 1); puts("введите ФИО студента: "); fflush(stdin); fgets(&att[rec]. FIO[0], 100, stdin); puts("введите оценку по математике"); scanf("%d", &att[rec]. math); puts("введите оценку по английскому языку"); scanf("%d", &att[rec]. eng); puts("введите оценку по физике"); scanf("%d", &att[rec]. phys); puts("введите оценку поведения"); fflush(stdin); fgets(&att[rec]. pov[0], 20, stdin); rec++; puts("прекратить работу? [y/n]"); scanf("%c", &ch); } while (ch == 'n'); Заполнение

for (int i = 0; i < rec; i++){ att[i]. aver = (att[i]. eng for (int i = 0; i < rec; i++){ att[i]. aver = (att[i]. eng + att[i]. math + att[i]. phys) / 3; } Расчет среднего балла for (int i = 0; i < rec; i++){ printf("Средний балл по аттестату %s = %. 2 lf n", att[i]. FIO, att[i]. aver); } _getch(); } Вывод результата на экран

. . . struct school { char FIO[100]; int math; int eng; int phys; . . . struct school { char FIO[100]; int math; int eng; int phys; char pov[20]; double aver; }; Пример 2 Объявление функций void Inp. Str(int, school*); void Avg. Str(int, school*); void Out. Str(school*); void main(){ school att[30], temp; char ch; setlocale(LC_CTYPE, "Russian"); int i, n;

puts(

void Inp. Str(int n, int i, school* stud){ Функция заполнения структур system( void Inp. Str(int n, int i, school* stud){ Функция заполнения структур system("cls"); printf("студент №%dn", i + 1); puts("введите ФИО студента: "); fflush(stdin); gets(stud->FIO); puts("введите оценку по математике"); scanf("%d", &stud->math); puts("введите оценку по английскому языку"); scanf("%d", &stud->eng); puts("введите оценку по физике"); scanf("%d", &stud->phys); puts("введите оценку поведения"); fflush(stdin); gets(stud->pov); } Обращение через указатель (косвенная адресация)

void Avg. Str(int n, school* stud){ Функция расчета среднего значения for (int i = void Avg. Str(int n, school* stud){ Функция расчета среднего значения for (int i = 0; i < n; i++){ stud->aver = (stud->eng + stud->math + stud->phys) / 3; } } void Out. Str(school* stud){ Функция вывода на печать printf("Средний балл по аттестату %s = %. 2 lf n", stud->FIO, stud ->aver); }

Копирование структур Копирование структур

Структуры одного типа можно присваивать другу. В этом случае оператор присваивания выполняет поверхностное копирование Структуры одного типа можно присваивать другу. В этом случае оператор присваивания выполняет поверхностное копирование бит за битом полей переменной-источника и перенесение их в соответствующие поля переменной-цели (обе структуры-переменные имеют одинаковый тип). С членами данных типа указатель могут возникнуть проблемы.

Копирование структур рекомендуется выполнять, используя функцию memcpy, string. h: memcpy(& destptr, & srcptr, sizeof(тип_структуры)); Копирование структур рекомендуется выполнять, используя функцию memcpy, string. h: memcpy(& destptr, & srcptr, sizeof(тип_структуры)); Копирует n байтов из srcptr в destptr и возвращает адрес destpt.

. . . struct school { char FIO[100]; int math; int eng; int phys; . . . struct school { char FIO[100]; int math; int eng; int phys; char pov[20]; double aver; } stud, univer; Объявление 2 -х переменных типа структуры void Cmp. Str(int n, school * stud, school * univer){ memcpy(univer->FIO, stud->FIO, sizeof(school)); } Копирование поля одной структуры в другую

Вложенные структуры Вложенные структуры

Элементами структуры могут быть массивы и другие структуры (исключение: тип void и функции). Элементами структуры могут быть массивы и другие структуры (исключение: тип void и функции).

. . . struct FIO { char name[50]; char surname[50]; }; struct school { . . . struct FIO { char name[50]; char surname[50]; }; struct school { FIO date; int math; int eng; int phys; char pov[20]; double aver; } stud; void Inp. Str(int, school*); void Out. Str(school*); void Avg. Str(int, school*); Пример 1 Объявление вложенной структуры Вложенная структура

void main(){ char ch; setlocale(LC_CTYPE, void main(){ char ch; setlocale(LC_CTYPE, "Russian"); int i, n; puts("Введите кол-во студентов"); scanf("%d", &n); school *stud = new school [n]; Set. Console. CP(1251); Set. Console. Output. CP(1251); for (int i = 0; i < n; i++){ Inp. Str(n, i, stud+i); Avg. Str(n, stud+i); } for (int i = 0; i < n; i++){ Out. Str(stud+i); } _getch(); }

void Inp. Str(int n, int i, school* stud){ system( void Inp. Str(int n, int i, school* stud){ system("cls"); printf("студент №%dn", i + 1); puts("введите фамилию студента: "); fflush(stdin); gets(stud->date. surname); puts("введите имя студента: "); fflush(stdin); gets(stud->date. name); puts("введите оценку по математике"); scanf("%d", &stud->math); puts("введите оценку по английскому языку"); scanf("%d", &stud->eng); puts("введите оценку по физике"); scanf("%d", &stud->phys); puts("введите оценку поведения"); fflush(stdin); gets(stud->pov); } Обращение к элементу вложенной структуры

void Avg. Str(int n, school* stud){ for (int i = 0; i < n; void Avg. Str(int n, school* stud){ for (int i = 0; i < n; i++){ stud->aver = (stud->eng + stud->math + stud->phys) / 3; } } void Out. Str(school* stud){ printf("Средний балл по аттестату %s = %. 2 lf n", stud>date. surname, stud->aver); }

. . . struct FIO { char name[50]; char surname[50]; }; struct school { . . . struct FIO { char name[50]; char surname[50]; }; struct school { FIO date; int math; int eng; int phys; char pov[20]; double aver; } stud; Пример 2

void Inp. Str(int); void Out. Str(int); void main(){ setlocale(LC_CTYPE, void Inp. Str(int); void Out. Str(int); void main(){ setlocale(LC_CTYPE, "Russian"); int pos = 1, n; while (pos > 0 && pos < 3){ system("cls"); puts("Выберите пункт меню: "); puts("-----------------------"); puts("1. Создать список"); puts(“ 2. Показать результат"); puts(“ 3. Выход"); puts("-----------------------"); scanf("%d", &pos);

switch (pos){ case 1: puts( switch (pos){ case 1: puts("Введите кол-во студентов"); scanf("%d", &n); Inp. Str(n); break; case 2: Out. Str(n); break; default: puts("Выход из программы. "); break; } } _getch(); } void Inp. Str(int n){ FILE *fp; school *stud = new school [n]; Set. Console. CP(1251); Set. Console. Output. CP(1251);

if ((fp = fopen( if ((fp = fopen("d: \@Work\Students. txt", "w")) == NULL) { printf("Cannot open file. n"); exit(1); } for (int i = 0; i < n; i++){ system("cls"); printf("студент №%dn", i + 1); puts("введите фамилию студента: "); fflush(stdin); gets(stud->date. surname); puts("введите имя студента: "); fflush(stdin); gets(stud->date. name); puts("введите оценку по математике"); scanf("%d", &stud->math); puts("введите оценку по английскому языку"); scanf("%d", &stud->eng); puts("введите оценку по физике"); scanf("%d", &stud->phys); puts("введите оценку поведения"); fflush(stdin); gets(stud->pov);

fwrite(stud, sizeof(school), 1, fp); } Блочная запись в файл fclose(fp); } void Out. Str(int fwrite(stud, sizeof(school), 1, fp); } Блочная запись в файл fclose(fp); } void Out. Str(int n){ FILE *fp; school *stud = new school[n]; Блочное чтение из файла if ((fp = fopen("d: \@Work\Students. txt", "r")) == NULL) { printf("Cannot open file. n"); exit(1); } while (fread(stud, sizeof(school), 1, fp)!=NULL){ printf("%s %10 s %5 d %10 d %10 s n", stud->date. surname, stud->date. name, stud->math, stud->eng, stud->phys, stud->pov); } fclose(fp); _getch(); }

Блочный ввод-вывод данных int fread (void *p, int size, int n, FILE *f); считывает Блочный ввод-вывод данных int fread (void *p, int size, int n, FILE *f); считывает n блоков по size байт каждый из файла f в область памяти с указателем p. int fwrite (void *p, int size, int n, FILE *f); записывает n блоков по size байт каждый из области памяти с указателем p в файл f.

Объединения Объединения

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

union <ID_объединения> { <описание полей>; }; Объединения применяются для : • инициализации объекта, если union { <описание полей>; }; Объединения применяются для : • инициализации объекта, если в каждый момент времени только один из многих объектов является активным; • для интерпретации представления одного типа данных в виде другого типа.

. . . union { char name 1; int number 2; long int number . . . union { char name 1; int number 2; long int number 3; } my. Union; int main() { setlocale(LC_CTYPE, "Rus"); my. Union. name 1 = 'N'; printf("Первое значение: %cn", my. Union. name 1); my. Union. number 2 = 222; printf("Второе значение: %dn", my. Union. number 2); my. Union. number 3 = 22222; printf("Третье значение: %dn", my. Union. number 3); printf("Первое значение: %c", my. Union. name 1); _getch(); } Пример 1

После того, как записали значение в элемент number 3 типа long int , уже После того, как записали значение в элемент number 3 типа long int , уже невозможно нормально обращаться к элементу name 1. Связано это с тем, что в их общую память уже записано значение long int, а переменная типа char неспособна работать с данными такого объема. Поэтому: . . . printf("Третье значение: %dn", my. Union. number 3); my. Union. name 1 = 'N'; printf("Первое значение: %c", my. Union. name 1); _getch(); }

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

Перечисления - это набор именованных целочисленных констант, определяющий все допустимые значения, которые может принимать Перечисления - это набор именованных целочисленных констант, определяющий все допустимые значения, которые может принимать переменная. Перечисления определяются с помощью ключевого слова enum, которое указывает на начало перечисляемого типа. Стандартный вид перечислений следующий: enum ID_типа { список перечислений}; Компилятор последовательно присваивает идентификаторам списка значений целочисленные величины 0, 1, . . . , . При необходимости можно явно задать значение идентификатора, тогда очередные элементы списка будут получать последующие возрастающие значения.

. . . enum level { parking, supermarket, restaurant, boutiques}; void main() { setlocale(LC_ALL, . . . enum level { parking, supermarket, restaurant, boutiques}; void main() { setlocale(LC_ALL, "rus"); level floor = parking; char out='0'; level fl = floor; while (out!='z') { system("cls"); puts( "Нажмите кнопку с номером этажа (от 0 до 3): "); scanf("%d", &fl); switch (fl) { case(parking) : puts("n. Вы спустились в паркинг!!!"); break; Пример 1

case(supermarket) : printf( case(supermarket) : printf("n. Вы на %d этаже!", supermarket); puts( "n. Здесь находится супермаркет. nn"); break; case(restaurant) : printf("n. Вы на %d этаже!", restaurant); puts("n. Здесь находится ресторан. nn"); break; case(boutiques) : printf("n. Вы на %d этаже!", boutiques); puts("n. Здесь находятся магазины. nn"); break; default: puts("n. Ошибка!"); } puts("Для выхода нажмите 'z' n"); if (_getch() == 'z') break; } }