Правила записи программы на языке Си 5 Правила формального описания синтаксиса языка программирования 6

Вид материалаЛекции
Подобный материал:
1   ...   20   21   22   23   24   25   26   27   28

13.Структуры языка C.


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

Отличие от массивов - элементы структуры разного типа.

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

Пример: товар на складе

название char name[21];

цена float price;

количество int number;

Все три переменных неразрывно связаны с каким-то товаром.

13.1.Описание структуры


1 способ

struct { char name[21];

float price;

int number;} goods;

Выделяется 27 байт для переменной goods;

2 способ

struct _GOODS { char name[21];

float price;

int number;};

Оператор не выделяет память, а устанавливает тип структуры. Для выделения памяти надо выдать оператор:

struct _GOODS goods1, goods2;

Выделяет память для goods1 и goods2, каждой по 27 байт.

Можно смепшать два способа:

struct _GOODS { char name[21];

float price;

int number;} goods;

Устанавливает тип структуры и выделяет память для goods.

3 способ. Используется оператор описания типа typedef:

typedef double real;


обычное описание

Если при описании имени стоит слово typedef, то описание не вы-

деляет память, а создает новый тип данных - real, который можно

применять также как и любое другое описание типа:

real a, b;

Еще пример:

typedef char string[40];


новый тип string

string a, b, c; - описание трех переменных, каждая из

которых является массивом из 40 символов.

В случае структуры имеем:

typedef struct { char name[21];

float price;

int number;} GOODS;

Описание типа

GOODS goods1, goods2; - выделение памяти для переменных

goods1 и goods2.

13.2.Трактовка имени структуры.


Имя структуры обозначает значение всей области памяти, которую она занимает. Поэтому для структур одного и того же типа допускается операция присваивания:


goods2 = goods1;

При этом вся область памяти goods1 копируется в область памяти goods2.

13.2.1.Доступ к элементу структуры.


Для этого используется операция ".".

goods1.name - образовалось составное имя. Тип составного имени такой же как тип соответствующего элемента структуры.

С составным именем можно выполнять любые действия, разрешенные для типа элемента.

goods2.price = 20*goods1.price;

scanf("%s", goods1.name);

goods1.name[3];

Из структур можно составить массив:

GOODS ab[50];

Тогда ab - адрес массива;

ab[2] - значение структуры;

ab[2].price - значение элемента структуры.

Структура может входить в другую структуру:

typedef struct { GOODS goods; int fl;} GF;

GF a - описание;

a.good.name

Никаких ограничений на уровень вложенности структур нет.

13.3.Инициализация структур.


Статические структуры могут быть проинициализированы подобно массивам:

static GOODS a = { "Телепвизор", 14000.0, 20};

Необходимо строго следитьза соответствием порядка констант порядку элементов структуры.

13.4.Структуры и функции.


Структура целиком может быть передана функции как параметр. Кроме того, структура может быть полностью возвращена как значение функции.

Пример:

typedef struct { double r, f;} POLAR;

typedef struct { double x, y;} DECART;

DECART ptod(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);

}