СТРУКТУРЫ Структуры Структура - это набор из одной или более переменных, возможно различных типов, сгруппированных под одним именем для удобства обработки.

Презентация:



Advertisements
Похожие презентации
Функции Функция – именованная последовательность описаний и операторов, выполняющая некоторое действие. Может иметь параметры и возвращать значение. Функция.
Advertisements

Полиморфизм Полиморфизм (polymorphism) - последний из трех "китов", на которых держится объектно-ориентированное программирование Слово это можно перевести.
УКАЗАТЕЛИ. Переменная - это именованная область памяти с заданным типом. [=значение]; int a; //Переменная типа integer с именем a int b=2;// Переменная.
Преобразования типов В языке C/C++ имеется несколько операций преобразования типов. Они используются в случае, если переменная одного типа должна рассматриваться.
Практическое занятие 6. Функции. Большинство языков программирования используют понятия функции и процедуры. C++ формально не поддерживает понятие процедуры,
Структуры и объединения Structures and unions НГТУ ИРИТ кафедра ИСУ Ольга Пронина.
Работа с файлами Сазонов Д.О. ПМиЭММ Часть 2. Тема занятия: Работа с файлами через потоки Для реализации файлового ввода/вывода, необходимо включить в.
Основы информатики Классы Заикин Олег Сергеевич zaikin.all24.org
Лекция 4 Программирование на Паскале. Элементы языка Турбо Паскаль 7.0. Типы данных. Управляющие конструкции.
Основы информатики Массивы. Указатели. Заикин Олег Сергеевич
Лекция 9 Функции. Массивы-параметры функции Передача массива в функцию Пример: void array_enter(int a[], int size) { int i; for (i = 0; i < size; i++)
Лекция 6 1. Обработка массивов. Объявление одномерного массива Синтаксис: [ ] Пример: int a[10]; Определяет массив a размера 10, т. е. блок из 10 последо-
МАССИВЫ 4 Определение 4 Описание 4 Обращение к элементам массива 4 Связь массивов с указателями 4 Примеры программ.
Переменная - это величина, которая имеет имя, тип и значение. Значение переменной может меняться во время выполнения программы. В компьютерах каждая переменная.
Программирование на языке Паскаль ЗАПИСИ в Паскале (RECORD)
Министерство образования Республики Беларусь Белорусский государственный университет Управляющие структуры языков программирования.
Инструкции C++ Условная инструкция Формат: if (условие) оператор; else оператор; Пример: if (i!=0) { if (j) j++; if(k) k++; else if(p) k--; } else i--;
Понятие строки. Операции со строковыми величинами. Стандартные процедуры и функции обработки строковых величин. Простые алгоритмы работы со строками на.
Глава 6. УПРАВЛЯЮЩИЕ СТРУКТУРЫ Оператор присваивания Простой и составной операторы Условный оператор Оператор множественного выбора Оператор цикла с предусловием.
Лекция 8 Область видимости Время жизни. Область видимости Область видимости – характеристика именованного объекта Область видимости - часть текста программы,
Транксрипт:

СТРУКТУРЫ

Структуры Структура - это набор из одной или более переменных, возможно различных типов, сгруппированных под одним именем для удобства обработки. Структура - это набор из одной или более переменных, возможно различных типов, сгруппированных под одним именем для удобства обработки. Традиционным примером структуры является учетная карточка работающего: "служащий" описывается набором атрибутов таких, как фамилия, имя, отчество (ф.и.о.), адрес, код социального обеспечения, зарплата и т.д. Некоторые из этих атрибутов сами могут оказаться структурами: ф.и.о. имеет несколько компонент, как и адрес, и даже зарплата. Традиционным примером структуры является учетная карточка работающего: "служащий" описывается набором атрибутов таких, как фамилия, имя, отчество (ф.и.о.), адрес, код социального обеспечения, зарплата и т.д. Некоторые из этих атрибутов сами могут оказаться структурами: ф.и.о. имеет несколько компонент, как и адрес, и даже зарплата. Структуры оказываются полезными при организации сложных данных особенно в больших программах, поскольку во многих ситуациях они позволяют сгруппировать связанные данные таким образом, что с ними можно обращаться, как с одним целым, а не как с отдельными объектами. Структуры оказываются полезными при организации сложных данных особенно в больших программах, поскольку во многих ситуациях они позволяют сгруппировать связанные данные таким образом, что с ними можно обращаться, как с одним целым, а не как с отдельными объектами.

Основные сведения Обратимся к процедурам преобразования даты. Дата состоит из нескольких частей таких, как день, месяц, год, день года и имя месяца. Эти пять переменных можно объединить в одну структуру вида: Обратимся к процедурам преобразования даты. Дата состоит из нескольких частей таких, как день, месяц, год, день года и имя месяца. Эти пять переменных можно объединить в одну структуру вида: struct date { struct date { int day; int day; int month; int month; int year; int year; int yearday; int yearday; char mon_name[4]; char mon_name[4]; }; }; Описание структуры, состоящее из заключенного в фигурные скобки списка описаний, начинается с ключевого слова struct. Описание структуры, состоящее из заключенного в фигурные скобки списка описаний, начинается с ключевого слова struct.

Основные сведения За словом struct может следовать необязательное имя, называемое ярлыком структуры (здесь это datе). Такой ярлык именует структуры этого вида и может использоваться в дальнейшем как сокращенная запись подробного описания. За словом struct может следовать необязательное имя, называемое ярлыком структуры (здесь это datе). Такой ярлык именует структуры этого вида и может использоваться в дальнейшем как сокращенная запись подробного описания. Элементы или переменные, упомянутые в структуре, называются членами. Ярлыки и члены структур могут иметь такие же имена, что и обычные переменные (т.е. не являющиеся членами структур), поскольку их имена всегда можно различить по контексту. Элементы или переменные, упомянутые в структуре, называются членами. Ярлыки и члены структур могут иметь такие же имена, что и обычные переменные (т.е. не являющиеся членами структур), поскольку их имена всегда можно различить по контексту. За правой фигурной скобкой, закрывающей список членов, может следовать список переменных. Оператор За правой фигурной скобкой, закрывающей список членов, может следовать список переменных. Оператор struct {...} x,y,z; struct {...} x,y,z; синтаксически аналогичен синтаксически аналогичен int x,y,z; int x,y,z;

Основные сведения Аналогичен в том смысле, что каждый из операторов описывает x, y и z в качестве переменных соответствующих типов и приводит к выделению для них памяти. Аналогичен в том смысле, что каждый из операторов описывает x, y и z в качестве переменных соответствующих типов и приводит к выделению для них памяти. Описание структуры, за которым не следует списка переменных, не приводит к выделению какой-либо памяти; оно только определяет шаблон или форму структуры. Однако, если такое описание снабжено ярлыком, то этот ярлык может быть использован позднее при определении фактических экземпляров структур. Например, если дано приведенное выше описание date, то struct date d определяет переменную d в качестве структуры типа date. Описание структуры, за которым не следует списка переменных, не приводит к выделению какой-либо памяти; оно только определяет шаблон или форму структуры. Однако, если такое описание снабжено ярлыком, то этот ярлык может быть использован позднее при определении фактических экземпляров структур. Например, если дано приведенное выше описание date, то struct date d определяет переменную d в качестве структуры типа date. Внешнюю или статическую структуру можно инициализировать, поместив вслед за ее определением список инициализаторов для ее компонент: Внешнюю или статическую структуру можно инициализировать, поместив вслед за ее определением список инициализаторов для ее компонент: struct date d={4, 7, 1776, 186, "jul"}; struct date d={4, 7, 1776, 186, "jul"};

Основные сведения Член определенной структуры может быть указан в выражении с помощью конструкции вида Член определенной структуры может быть указан в выражении с помощью конструкции вида имя структуры. член имя структуры. член Операция указания члена структуры "." связывает имя структуры и имя члена. В качестве примера определим leap (признак високосности года) на основе даты, находящейся в структуре d, Операция указания члена структуры "." связывает имя структуры и имя члена. В качестве примера определим leap (признак високосности года) на основе даты, находящейся в структуре d, leap = d.year%4 == 0 && d.year%100 != 0 || d.year%400 == 0; leap = d.year%4 == 0 && d.year%100 != 0 || d.year%400 == 0; или проверим имя месяца или проверим имя месяца if (strcmp(d.mon_name, "aug") == 8)... if (strcmp(d.mon_name, "aug") == 8)...

Основные сведения Структуры могут быть вложенными; учетная карточка служащего может фактически выглядеть так: Структуры могут быть вложенными; учетная карточка служащего может фактически выглядеть так: struct person { struct person { char name[namesize]; char name[namesize]; char address[adrsize]; char address[adrsize]; long zipcode; /* почтовый индекс */ long zipcode; /* почтовый индекс */ long ss_number; /* код соц. обеспечения */ long ss_number; /* код соц. обеспечения */ double salary; /* зарплата */ double salary; /* зарплата */ struct date birthdate; /* дата рождения */ struct date birthdate; /* дата рождения */ struct date hiredate; /* дата поступления на работу */ struct date hiredate; /* дата поступления на работу */ }; };

Основные сведения Структура person содержит две структуры типа date. Если мы определим emp как Структура person содержит две структуры типа date. Если мы определим emp как struct person emp; struct person emp; то то emp.birthdate.month emp.birthdate.month будет ссылаться на месяц рождения. Операция указания члена структуры "." ассоциируется слева направо. будет ссылаться на месяц рождения. Операция указания члена структуры "." ассоциируется слева направо.

Структуры и функции В языке "C" существует ряд ограничений на использование структур. Единственные операции, которые вы можете проводить со структурами, состоят в определении ее адреса с помощью операции & и доступе к одному из ее членов. Это влечет за собой то, что структуры нельзя присваивать или копировать как целое, и что они не могут быть переданы функциям или возвращены ими. На указатели структур эти ограничения не накладываются, так что структуры и функции все же могут работать совместно. Автоматические структуры, как и автоматические массивы, не могут быть инициализированы; инициализация возможна только в случае внешних или статических структур. В языке "C" существует ряд ограничений на использование структур. Единственные операции, которые вы можете проводить со структурами, состоят в определении ее адреса с помощью операции & и доступе к одному из ее членов. Это влечет за собой то, что структуры нельзя присваивать или копировать как целое, и что они не могут быть переданы функциям или возвращены ими. На указатели структур эти ограничения не накладываются, так что структуры и функции все же могут работать совместно. Автоматические структуры, как и автоматические массивы, не могут быть инициализированы; инициализация возможна только в случае внешних или статических структур. Поскольку правила языка запрещают передачу структуры в функции, то мы должны либо передавать отдельно компоненты, либо передать указатель всей структуры. Поскольку правила языка запрещают передачу структуры в функции, то мы должны либо передавать отдельно компоненты, либо передать указатель всей структуры.

Структуры и функции Первая возможность демонстрируется на примере функции day_of_year Первая возможность демонстрируется на примере функции day_of_year d.yearday = day_of_year(d.year, d.month, d.day); d.yearday = day_of_year(d.year, d.month, d.day); другой способ состоит в передаче указателя. Если мы опишем hiredate как другой способ состоит в передаче указателя. Если мы опишем hiredate как struct date hiredate; struct date hiredate; и перепишем day_of_year нужным образом, мы сможем тогда написать и перепишем day_of_year нужным образом, мы сможем тогда написать hiredate.yearday = day_of_year(&hiredate); hiredate.yearday = day_of_year(&hiredate); передавая указатель на hiredate функции day_of_year. Функция должна быть модифицирована, потому что ее аргумент теперь является указателем, а не списком переменных: передавая указатель на hiredate функции day_of_year. Функция должна быть модифицирована, потому что ее аргумент теперь является указателем, а не списком переменных:

Структуры и функции static int day_tab[2][13] = { static int day_tab[2][13] = { (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31), (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31), (0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31) }; (0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31) }; day_of_year(pd) /* set day of year from month, day */ day_of_year(pd) /* set day of year from month, day */ struct date *pd; struct date *pd; { int i, day, leap; int i, day, leap; day = pd->day; day = pd->day; leap = pd->year%4 == 0 && pd->year%100!=0 || pd- >year%400 == 0; leap = pd->year%4 == 0 && pd->year%100!=0 || pd- >year%400 == 0; for (i =1; i month; i++) day += day_tab[leap][i]; for (i =1; i month; i++) day += day_tab[leap][i]; return(day); return(day); }

Структуры и функции Описание struct date *pd говорит, что pd является указателем структуры типа date. Описание struct date *pd говорит, что pd является указателем структуры типа date. Запись pd->year является новой. Если p - указатель на структуру, то p-> член структуры обращается к конкретному члену. Так как pd указывает на структуру, то к члену year можно обратиться и следующим образом (*pd).year Запись pd->year является новой. Если p - указатель на структуру, то p-> член структуры обращается к конкретному члену. Так как pd указывает на структуру, то к члену year можно обратиться и следующим образом (*pd).year но указатели структур используются настолько часто, что запись -> оказывается удобным сокращением. Круглые скобки в (*pd).year необходимы, потому что операция указания члена структуры старше, чем *. Обе операции, "- >" и ".", ассоциируются слева направо, так что конструкции слева и справа эквивалентны: но указатели структур используются настолько часто, что запись -> оказывается удобным сокращением. Круглые скобки в (*pd).year необходимы, потому что операция указания члена структуры старше, чем *. Обе операции, "- >" и ".", ассоциируются слева направо, так что конструкции слева и справа эквивалентны: p->q->memb (p->q)->memb p->q->memb (p->q)->memb emp.birthdate.month(emp.birthdate).month emp.birthdate.month(emp.birthdate).month

Структуры и функции Для полноты ниже приводится другая функция, month_day, переписанная с использованием структур. Для полноты ниже приводится другая функция, month_day, переписанная с использованием структур. month_day(pd) /* set month and day from day of year */ month_day(pd) /* set month and day from day of year */ struct date *pd; struct date *pd; { int i, leap; int i, leap; leap = pd->year % 4 == 0 && pd->year % 100 != 0 || pd- >year % 400 == 0; leap = pd->year % 4 == 0 && pd->year % 100 != 0 || pd- >year % 400 == 0; pd->day = pd->yearday; pd->day = pd->yearday; for (i = 1; pd->day > day_tab[leap][i]; i++) for (i = 1; pd->day > day_tab[leap][i]; i++) pd->day -= day_tab[leap][i]; pd->day -= day_tab[leap][i]; pd->month = i; pd->month = i; }

Структуры и функции Операции работы со структурами "->" и "." наряду со () для списка аргументов и [] для индексов находятся на самом верху иерархии старшинства операций и, следовательно, связываются очень крепко. Если, например, имеется описание Операции работы со структурами "->" и "." наряду со () для списка аргументов и [] для индексов находятся на самом верху иерархии старшинства операций и, следовательно, связываются очень крепко. Если, например, имеется описание struct { struct { int x; int x; int *y; int *y; } *p; } *p; то выражение ++p->x увеличивает х, а не р, так как оно эквивалентно выражению ++(p->х). Для изменения порядка выполнения операций можно использовать круглые скобки: (++p)->х увеличивает p до доступа к х, а (p++)->x увеличивает p после. то выражение ++p->x увеличивает х, а не р, так как оно эквивалентно выражению ++(p->х). Для изменения порядка выполнения операций можно использовать круглые скобки: (++p)->х увеличивает p до доступа к х, а (p++)->x увеличивает p после.

Структуры и функции Совершенно аналогично *p->y извлекает то, на что указывает y; *p->y++ увеличивает y после обработки того, на что он указывает; (*p->y)++ увеличивает то, на что указывает y; *p++->y увеличивает p после выборки того, на что указывает y. Совершенно аналогично *p->y извлекает то, на что указывает y; *p->y++ увеличивает y после обработки того, на что он указывает; (*p->y)++ увеличивает то, на что указывает y; *p++->y увеличивает p после выборки того, на что указывает y.

Массивы структур Структуры особенно подходят для управления массивами связанных переменных. Рассмотрим, например, программу подсчета числа вхождений каждого ключевого слова языка "C". Нам нужен массив символьных строк для хранения имен и массив целых для подсчета. одна из возможностей состоит в использовании двух параллельных массивов keyword и keycount: Структуры особенно подходят для управления массивами связанных переменных. Рассмотрим, например, программу подсчета числа вхождений каждого ключевого слова языка "C". Нам нужен массив символьных строк для хранения имен и массив целых для подсчета. одна из возможностей состоит в использовании двух параллельных массивов keyword и keycount: char *keyword [nkeys]; char *keyword [nkeys]; int keycount [nkeys]; int keycount [nkeys]; Но сам факт, что массивы параллельны, указывает на возможность другой организации. Каждое ключевое слово здесь по существу является парой: Но сам факт, что массивы параллельны, указывает на возможность другой организации. Каждое ключевое слово здесь по существу является парой: char *keyword; char *keyword; int keycount; int keycount;

Массивы структур Следовательно, имеется массив пар. Описание структуры Следовательно, имеется массив пар. Описание структуры struct key { struct key { char *keyword; char *keyword; int keycount; int keycount; } keytab [nkeys]; } keytab [nkeys]; определяет массив keytab структур такого типа и отводит для них память. Каждый элемент массива является структурой. Это можно было бы записать и так: определяет массив keytab структур такого типа и отводит для них память. Каждый элемент массива является структурой. Это можно было бы записать и так: struct key { struct key { char *keyword; char *keyword; int keycount; int keycount; }; }; struct key keytab [nkeys]; struct key keytab [nkeys];

Массивы структур Так как структура keytab фактически содержит постоянный набор имен, то легче всего инициализировать ее один раз и для всех членов при определении: Так как структура keytab фактически содержит постоянный набор имен, то легче всего инициализировать ее один раз и для всех членов при определении: struct key { struct key { char *keyword; char *keyword; int keycount; int keycount; } keytab[ ] ={ "break", 0, } keytab[ ] ={ "break", 0, "case", 0, "case", 0, "char", 0, "char", 0, "continue", 0, "continue", 0, "default", 0, "default", 0, /*... */ /*... */ "while", 0 }; "while", 0 };

Массивы структур Инициализаторы перечисляются парами соответственно членам структуры. Было бы более точно заключать в фигурные скобки инициализаторы для каждой "строки" или структуры следующим образом: Инициализаторы перечисляются парами соответственно членам структуры. Было бы более точно заключать в фигурные скобки инициализаторы для каждой "строки" или структуры следующим образом: { "break", 0 }, { "break", 0 }, { "case", 0 }, { "case", 0 }, Но когда инициализаторы являются простыми переменными или символьными строками и все они присутствуют, то во внутренних фигурных скобках нет необходимости. Как обычно, компилятор сам вычислит число элементов массива keytab, если инициализаторы присутствуют, а скобки [ ] оставлены пустыми. Но когда инициализаторы являются простыми переменными или символьными строками и все они присутствуют, то во внутренних фигурных скобках нет необходимости. Как обычно, компилятор сам вычислит число элементов массива keytab, если инициализаторы присутствуют, а скобки [ ] оставлены пустыми.

Массивы структур В языке "C" предусмотрена унарная операция sizeof, выполняемая во время компиляции, которая позволяет вычислить размер любого объекта. Выражение В языке "C" предусмотрена унарная операция sizeof, выполняемая во время компиляции, которая позволяет вычислить размер любого объекта. Выражение sizeof(object) sizeof(object) выдает целое, равное размеру указанного объекта. (Размер определяется в неспецифицированных единицах, называемых "байтами", которые имеют тот же размер, что и переменные типа char). Объект может быть фактической переменной, массивом и выдает целое, равное размеру указанного объекта. (Размер определяется в неспецифицированных единицах, называемых "байтами", которые имеют тот же размер, что и переменные типа char). Объект может быть фактической переменной, массивом и структурой, или именем основного типа, как int или double, или именем производного типа, как структура. структурой, или именем основного типа, как int или double, или именем производного типа, как структура.

Указатели на структуры Чтобы проиллюстрировать некоторые соображения, связанные с использованием указателей и массивов структур, составим программу подсчета ключевых строк, используя указатели: Чтобы проиллюстрировать некоторые соображения, связанные с использованием указателей и массивов структур, составим программу подсчета ключевых строк, используя указатели: main() /* count c keyword; pointer version */ main() /* count c keyword; pointer version */ { int t; char word[maxword]; { int t; char word[maxword]; struct key *binary(), *p; struct key *binary(), *p; while ((t = getword(word, maxword;) !=eof) while ((t = getword(word, maxword;) !=eof) if (t==letter) if (t==letter) if ((p=binary(word,keytab,nkeys)) !=null) if ((p=binary(word,keytab,nkeys)) !=null) p->keycount++; p->keycount++; for (p=keytab; p>keytab + nkeys; p++) for (p=keytab; p>keytab + nkeys; p++) if (p->keycount > 0) if (p->keycount > 0) printf("%4d %s/n", p->keycount, p->keyword); printf("%4d %s/n", p->keycount, p->keyword); } } struct key *binary(word, tab, n) /* find word */ struct key *binary(word, tab, n) /* find word */ char *word /* in tab[0]...tab[n-1] */ char *word /* in tab[0]...tab[n-1] */ struct key tab []; struct key tab []; int n; int n; { { int cond; int cond; struct key *low = &tab[0]; struct key *low = &tab[0]; struct key *high = &tab[n-1]; struct key *high = &tab[n-1]; struct key *mid; struct key *mid; while (low 0) else if (cond > 0) low = mid + 1; low = mid + 1; else else return(mid); return(mid); } } return(null); return(null); } } Здесь имеется несколько моментов, которые стоит отметить. Во-первых, описание функции binary должно указывать, что она возвращает указатель на структуру типа key, а не на целое; это объявляется как в функции main, так и в binary. Если функция binary находит слово, то она возвращает указатель на него; если же нет, она возвращает NULL. Здесь имеется несколько моментов, которые стоит отметить. Во-первых, описание функции binary должно указывать, что она возвращает указатель на структуру типа key, а не на целое; это объявляется как в функции main, так и в binary. Если функция binary находит слово, то она возвращает указатель на него; если же нет, она возвращает NULL. Во-вторых, все обращения к элементам массива keytab осуществляются через указатели. В функции main мы написали Во-вторых, все обращения к элементам массива keytab осуществляются через указатели. В функции main мы написали for (p=keytab; p < keytab + nkeys; p++) for (p=keytab; p < keytab + nkeys; p++) Если p является указателем структуры, то любая арифметика с p учитывает фактический размер данной структуры, так что p++ увеличивает p на нужную величину, в результате чего p указывает на следующий элемент массива структур. Но не считайте, что размер структуры равен сумме размеров ее членов, - из-за требований выравнивания для различных объектов в структуре могут возникать "дыры". Если p является указателем структуры, то любая арифметика с p учитывает фактический размер данной структуры, так что p++ увеличивает p на нужную величину, в результате чего p указывает на следующий элемент массива структур. Но не считайте, что размер структуры равен сумме размеров ее членов, - из-за требований выравнивания для различных объектов в структуре могут возникать "дыры". И, наконец, несколько второстепенный вопрос о форме записи программы. Если возвращаемая функцией величина имеет тип, как, например, в И, наконец, несколько второстепенный вопрос о форме записи программы. Если возвращаемая функцией величина имеет тип, как, например, в struct key *binary(word, tab, n) struct key *binary(word, tab, n) то может оказаться, что имя функции трудно выделить среди текста. В связи с этим иногда используется другой стиль записи: то может оказаться, что имя функции трудно выделить среди текста. В связи с этим иногда используется другой стиль записи: struct key * struct key * binary(word, tab, n) binary(word, tab, n)

Указатели на структуры Чтобы проиллюстрировать некоторые соображения, связанные с использованием указателей и массивов структур, составим программу подсчета ключевых строк, используя указатели: Чтобы проиллюстрировать некоторые соображения, связанные с использованием указателей и массивов структур, составим программу подсчета ключевых строк, используя указатели: main() /* count c keyword; pointer version */ main() /* count c keyword; pointer version */ { int t; char word[maxword]; struct key *binary(), *p; { int t; char word[maxword]; struct key *binary(), *p; while ((t = getword(word, maxword;) !=eof) while ((t = getword(word, maxword;) !=eof) if (t==letter) if (t==letter) if ((p=binary(word,keytab,nkeys)) !=null) if ((p=binary(word,keytab,nkeys)) !=null) p->keycount++; p->keycount++; for (p=keytab; p>keytab + nkeys; p++) for (p=keytab; p>keytab + nkeys; p++) if (p->keycount > 0) printf("%d %s\n", p->keycount, p- >keyword); } if (p->keycount > 0) printf("%d %s\n", p->keycount, p- >keyword); }

Указатели на структуры struct key *binary(word, tab, n) /* find word in tab[n] */ struct key *binary(word, tab, n) /* find word in tab[n] */ char *word; struct key tab []; int n; char *word; struct key tab []; int n; { int cond; struct key *low = &tab[0]; { int cond; struct key *low = &tab[0]; struct key *high = &tab[n-1]; struct key *mid; struct key *high = &tab[n-1]; struct key *mid; while (low 0) low = mid + 1; else return(mid); else return(mid); } } return(null); return(null); } }

Указатели на структуры Здесь имеется несколько моментов, которые стоит отметить. Во-первых, описание функции binary должно указывать, что она возвращает указатель на структуру типа key, а не на целое; это объявляется как в функции main, так и в binary. Если функция binary находит слово, то она возвращает указатель на него; если же нет, она возвращает NULL. Здесь имеется несколько моментов, которые стоит отметить. Во-первых, описание функции binary должно указывать, что она возвращает указатель на структуру типа key, а не на целое; это объявляется как в функции main, так и в binary. Если функция binary находит слово, то она возвращает указатель на него; если же нет, она возвращает NULL. Во-вторых, все обращения к элементам массива keytab осуществляются через указатели. В функции main мы написали Во-вторых, все обращения к элементам массива keytab осуществляются через указатели. В функции main мы написали for (p=keytab; p < keytab + nkeys; p++) for (p=keytab; p < keytab + nkeys; p++) Если p является указателем структуры, то любая арифметика с p учитывает фактический размер данной структуры, так что p++ увеличивает p на нужную величину, в результате чего p указывает на следующий элемент массива структур. Если p является указателем структуры, то любая арифметика с p учитывает фактический размер данной структуры, так что p++ увеличивает p на нужную величину, в результате чего p указывает на следующий элемент массива структур.

Указатели на структуры Но не считайте, что размер структуры равен сумме размеров ее членов, - из-за требований выравнивания для различных объектов в структуре могут возникать "дыры". Но не считайте, что размер структуры равен сумме размеров ее членов, - из-за требований выравнивания для различных объектов в структуре могут возникать "дыры". И, наконец, несколько второстепенный вопрос о форме записи программы. Если возвращаемая функцией величина имеет тип, как, например, в И, наконец, несколько второстепенный вопрос о форме записи программы. Если возвращаемая функцией величина имеет тип, как, например, в struct key *binary(word, tab, n) struct key *binary(word, tab, n) то может оказаться, что имя функции трудно выделить среди текста. В связи с этим иногда используется другой стиль записи: то может оказаться, что имя функции трудно выделить среди текста. В связи с этим иногда используется другой стиль записи: struct key * struct key * binary(word, tab, n) binary(word, tab, n)

Определение типа В языке "C" предусмотрена возможность, называемая typedef для введения новых имен для типов данных. Например, описание typedef int length; делает имя length синонимом для int. "Тип" length может быть использован в описаниях, переводов типов и т.д. Точно таким же образом, как и тип int: В языке "C" предусмотрена возможность, называемая typedef для введения новых имен для типов данных. Например, описание typedef int length; делает имя length синонимом для int. "Тип" length может быть использован в описаниях, переводов типов и т.д. Точно таким же образом, как и тип int: length len, maxlen; length len, maxlen; length *lengths[]; length *lengths[]; Аналогично описанию Аналогично описанию typedef char *string; typedef char *string; делает string синонимом для char*, то есть для указателя на символы, что затем можно использовать в описаниях вида делает string синонимом для char*, то есть для указателя на символы, что затем можно использовать в описаниях вида string p, lineptr[lines], alloc(); string p, lineptr[lines], alloc();

Определение типа Объявляемый в конструкции typedef тип появляется в позиции имени переменной, а не сразу за словом typedef. Синтаксически конструкция typedef подобна описаниям класса памяти extern, static и т. д. Объявляемый в конструкции typedef тип появляется в позиции имени переменной, а не сразу за словом typedef. Синтаксически конструкция typedef подобна описаниям класса памяти extern, static и т. д. Необходимо подчеркнуть, что описание typedef не приводит к созданию нового в каком-либо смысле типа; оно только добавляет новое имя для некоторого существующего типа. При этом не возникает и никакой новой семантики: описанные таким способом переменные обладают точно теми же свойствами, что и переменные, описанные явным образом. По существу конструкция typedef сходна с #define за исключением того, что она интерпретируется компилятором и потому может осуществлять подстановки текста, которые выходят за пределы возможностей макропроцессора языка "C". Необходимо подчеркнуть, что описание typedef не приводит к созданию нового в каком-либо смысле типа; оно только добавляет новое имя для некоторого существующего типа. При этом не возникает и никакой новой семантики: описанные таким способом переменные обладают точно теми же свойствами, что и переменные, описанные явным образом. По существу конструкция typedef сходна с #define за исключением того, что она интерпретируется компилятором и потому может осуществлять подстановки текста, которые выходят за пределы возможностей макропроцессора языка "C".

Определение типа Имеются две основные причины применения описаний typedef. Первая причина связана с параметризацией программы, чтобы облегчить решение проблемы переносимости. Если для типов данных, которые могут быть машинно-зависимыми, использовать описание typedef, то при переносе программы на другую машину придется изменить только эти описания. Одна из типичных ситуаций состоит в использовании определяемых с помощью typedef имен для различных целых величин и в последующем подходящем выборе типов short, int и long для каждой имеющейся машины. Имеются две основные причины применения описаний typedef. Первая причина связана с параметризацией программы, чтобы облегчить решение проблемы переносимости. Если для типов данных, которые могут быть машинно-зависимыми, использовать описание typedef, то при переносе программы на другую машину придется изменить только эти описания. Одна из типичных ситуаций состоит в использовании определяемых с помощью typedef имен для различных целых величин и в последующем подходящем выборе типов short, int и long для каждой имеющейся машины. Второе назначение typedef состоит в обеспечении лучшей документации для программы - тип с именем treeptr может оказаться более удобным для восприятия, чем тип, который описан только как указатель сложной структуры. Второе назначение typedef состоит в обеспечении лучшей документации для программы - тип с именем treeptr может оказаться более удобным для восприятия, чем тип, который описан только как указатель сложной структуры.