Лекции Булатицкий Дмитрий Иванович (во многом по материалам Прасолова А. Н.)
Скачать 319.62 Kb.
|
Структуры языка СиПод структурой понимают совокупность элементов данных разного типа, лежащих в непрерывной области памяти и объединенных общим именем. Отличие от массивов - элементы структуры разного типа. Необходимость: часто реальный объект характеризуется величинами разного типа. Пример: товар на складе название char name[21]; цена float price; количество int number; Все три переменных неразрывно связаны с каким-то товаром. Оператор typedefЕсли к описанию double real; //описана переменная real типа double дописать зарезервированное слово typedef, то оператор превратится в описание типа: typedef double real; // описан новый тип, соответствующий типу double Если при описании имени стоит слово typedef, то описание не выделяет память, а создает новый тип данных - real, который можно применять также как и любое другое описание типа: real a, b; Еще пример: typedef char string40[40]; // новый тип string40 string40 a, b, c; //описание трех переменных, каждая из которых является массивом из 40 символов. Описание структурыВ данном пункте рассмотрен лишь упрощённый синтаксис описания структур С++ struct Goods { char name[21]; float price; int number; }; Оператор не выделяет память, а устанавливает тип структуры. Для выделения памяти надо выдать оператор: struct _GOODS goods1, goods2; Выделяет память для goods1 и goods2, каждой по 29 байт. sruct date { int day; int month; int year; }; Трактовка имени структурыИмя структуры обозначает значение всей области памяти, которую она занимает. Поэтому для структур одного и того же типа допускается операция присваивания: goods2 = goods1; При этом вся область памяти goods1 копируется в область памяти goods2. Доступ к элементу структурыДля этого используется операция ".". goods1.name - образовалось составное имя. Тип составного имени такой же как тип соответствующего элемента структуры. С составным именем можно выполнять любые действия, разрешенные для типа элемента. goods2.price = 20*goods1.price; scanf("%s", goods1.name); goods1.name[3]; Из структур можно составить массив: GOODS ab[50]; Тогда ab - адрес массива; ab[2] - значение структуры; ab[2].price - значение элемента структуры. Инициализация структурСтруктуры могут быть проинициализированы подобно массивам: static GOODS a = {"Телепвизор", 14000.0, 20}; Необходимо строго следить за соответствием порядка констант порядку элементов структуры. Структуры и функцииСтруктура целиком может быть передана функции как параметр. Кроме того, структура может быть полностью возвращена как значение функции. Пример: typedef struct { double r, f;} Polar; typedef struct { double x, y;} Decart; Decart PoarToDecart(Polar pcoord) { DECART dcoord; dcoord.x = pcoord.r*cos(pcoord.f); dcoord.y = pcoord.r*sin(pcoord.f); return dcoord; } void main(void) { DECART a; POLAR b = { 15.2, 0.18}; a = ptod(b); . . . } Для больших структур такой способ передачи параметров и возврата значений неэффективен, так как компилятору приходится создавать копии параметров и результатов работы функции в специальной области памяти. Значиительно эффективнее передавать адреса параметров: void prot (DECART*dc, POLAR*pc) { (*dc).x = (*pc).r*cos((*pc).f); (*dc).y = (*pc).r*cos((*pc).f); } (*dc) в скобках потому, что "." имеет более высший приоритет. Головная программа при этом выглядит так: void main(void) { DECART a; POLAR b = { 15.2, 0.18}; ptod(&a, &b); . . . } Запись вида (*dc).x громоздка и плохо понятна. Поэтому разработчики языка C предусмотрели более понятную эквивалентную запись: (*dc).x эквивалентно dc->x. Используя ее: void ptod(DECART *dc, POLAR *pc) { dc->x = pc->r*cos(pc->f); dc->y = pc->r*sin(pc->f); } |