Структурный тип данных (структуры)

В языке Си понятие структуры аналогично понятию записи (record) в языке Паскаль. Структурный тип данных обычно используется при разработке информационных систем, баз данных.

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

В отношении структуры можно выполнять следующие действия: копировать; выполнять операции присваивания; передавать функциям в качестве аргумента, а функции могут возвращать их в качестве результата; инициализировать. Структуры нельзя сравнивать.

Синтаксис описания структуры:

struct [имя типа]

{ тип 1 переменная 1;

тип 2 переменная 2;

…………………..…….;

тип n переменная n;

};

Описание начинается со служебного слова struct, за которым может следовать имя типа структуры. Далее это имя может служить кратким обозначением той части описания, которая заключена в фигурные скобки. В фигурных скобках определяется последовательность переменных величин, называемых элементами структуры, которые могут иметь различные типы. В конце обязательно ставится символ «;»
(т.к. это оператор).

Объявления переменных списка имеют тот же самый синтаксис, что и объявление обычных переменных, за исключением того, что объявления не могут содержать спецификаторов классов памяти или начальных значений. Элементы структуры могут быть любого типа (базового, массивом, указателем, объединением или структурой). Их имена могут совпадать с именем обычных переменных, т.к. они всегда различны по контексту.

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

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

Например, требуется организовать сведения о выплате студентам стипендии:

Студент
Курс
Группа
Стипендия
Фамилия

Элементы такой структуры (фамилия, курс, группа, стипендия) называются полями. Каждому полю должно быть поставлено в соответствие имя и тип.

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

Struct student

{

char fam[30];

int kurs;

char grup[3];

float stip;

};

После этого student становится именем структурного типа, который может быть назначен некоторым переменным.

В соответствии со стандартом Си это нужно делать так:

struct student stud1, stud2;

Служебное слово struct можно опускать и писать так:

student stud1, stud2;

где stud1 и stud2 – переменные структурного типа.

Допускаются и другие варианты описания структурных переменных. Можно вообще не задавать имя типа, а описывать сразу переменные:

Struct

{

char fam[30];

int kurs;

char grup[3];

float stip;

} stud1, stud2;

Обращение к элементам (полям) структурной величины производится с помощью уточненного имени следующего формата:

Имя структуры.имя элемента

Примеры уточненных имен для описанных выше переменных:

stud1.fam;

stud1.stip;

Значения элементов структуры могут определяться вводом, присваиванием, инициализацией.

Пример инициализации в описании:

student stud1 = {"Кротов", 3, "Ф32", 350};

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

Допускается использование массивов структур. Например, сведения о 100 студентах могут храниться в массиве, описанном следующим образом:

student stud[100];

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

stud[0].fam; - фамилия первого студента

stud[4].kurs; - курс пятого студента

stud[9].stip; - стипендия 10 студента и т.п.

Если нужно взять первую букву фамилии 25 студента, то следует писать так:

stud[24].fam[0];

ФУНКЦИИ В ЯЗЫКЕ СИ

Язык Сипредоставляет программисту большие возможности в определении структуры программы. Качество программы зависит от умения программиста разбить свою программу на логически обоснованные функции (модули) с хорошо обоснованным интерфейсом и хорошо документированным текстом программы. Функция является основной программной единицей в языке Си, минимальным исполняемым программным модулем. В языке Си нет понятий подпрограммы, вся выполняемая часть программы строится на последовательности определений и функций.

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

В языке Си существует два вида функций:

1) Функции, возвращающие значения в вызывающую программу.

Синтаксис записи:

[класс памяти] тип функции имя функции (список и определение формальных параметров)

{

тело функции (операторы);

return (выражение);

}

где

класс памяти - это спецификатор, который определяет класс памяти функции;

тип функции - определяет тип результата возвращаемого функцией, с помощью оператора return;

имя функции – идентификатор, с помощью которого функция вызывается для выполнения;

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

тело функциисостоит из определения внутренних переменных и операторов;

return – оператор возврата, которым обязательно заканчивается функция, возвращающая значение в точку её вызова;

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

Если функция возвращает значение результата с помощью оператора return, то такую функцию можно использовать в выражениях правой части оператора присваивания и во всех выражениях, где допустимо значение результата функции. В качестве результата функция не может возвращать массив или функцию, но может возвращать указатель на массив или функцию.

2) Функции, не возвращающие значения в вызываемую программу.

Синтаксис записи:

[класс памяти] void имя функции (список и определение формальных параметров)

{

тело функции (операторы);

[return();]

}

Выполнение такой функции завершается либо оператором возврата без параметров (return();), либо после того как выполняется тело функции.

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

Синтаксис записи прототипа функции:

[класс памяти] тип функции или void имя функции(список и определение формальных параметров);

Прототип функции должен размещаться в разделе внешних параметров, сразу за директивами препроцессора. Прототипы функции указывать не обязательно, если главная функция main() записана в программе после всех других функций. Если выше, то обязательно. Если в описании функции не указан класс памяти, то по умолчанию берётся внешний.

Вызов функции активизирует её, т.е. передаёт ей управление и фактические параметры.

Синтаксис вызова функции:

имя функции (список фактических параметров);

или

указатель на функцию (список фактических параметров);

где указатель на функцию – это выражение, имеющее в своём значении адрес некоторой функции.

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

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

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

Наши рекомендации