Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
114-124.docx
Скачиваний:
4
Добавлен:
11.09.2019
Размер:
121.04 Кб
Скачать

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

Мы видели, как инициализируются переменные и массивы:

int count = 0;

static int fibo [] = {0, 1, 1, 2, 3, 5, 8};

Инициализации структуры аналагична инициализации простых переменных или массивов. Допускается выполнение инициализации элементов структуры. Классы памяти оказывают влияние на структуры аналогично обычным идентификаторам.

Можно ли инициализировать и структурную переменную? Да, если структурная переменная будет внешней или статической. Здесь следует иметь в виду, что принадлежность структурной переменной к внешнему типу зависит от того, где определена переменная, а не где определен шаблон. В нашем примере шаблон book является внешним, а переменная libry — внутренней, так как она определена внутри функции и по умолчанию располагается в классе автоматической памяти. Предположим, мы создали такое описание:

static struct book libry;

В этом случае используется статическая память, и можно инициализировать структуру следующим способом:

static struct book libry = {

"Пират и девица",

"Рене Вивот",

1р.95

};

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

Продолжим наши разъяснения свойств структуры.

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

Структура является разновидностью супермассива, в котором один элемент может быть массивом типа char, следующий — float и еще один int. Обычно можно обращаться к отдельным элементам массива, используя индекс. Как это сделать для отдельных элементов структуры? Для этого мы используем символ ".", обозначающий операцию получения элемента структуры. Например, libry.value является элементом value структуры libry. Можно применять libry.value точно так же, как вы использовали бы любую другую переменную типа float. Можно применять и libry.title точно так же, как массив типа char. Поэтому мы могли бы использовать выражения, подобные

gets (libry.title)

и

scanf (" %f" , &libry.value);

В сущности .title, .author и .value играют роль индексов для структуры book.

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

struct book spiro; gerald;

gets (spiro.title); gets (gerald.title);

.title ссылается на первый элемент структуры book.

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

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

Передача структур в функции.

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

fname(stvariable);

Если переменная stused_boat описана как локальная для main() и ее объявление передается в функцию, то эту переменную можно передать в функцию с именем vprint_data() при помощи оператора:

vprint_data(stused_boat);

Как можно догадаться, в прототипе функции vprint_data() нужно объявить тип принимаемой структуры:

/* Объявление структуры, допустимое в С и C++ */

void vprint_data(struct stboat stany_boat);

// Объявление структуры, возможное только в C++//

void vprint_data(stboat stany_boat);

Если передавать полные копии структур в функции, то нередко можно снизить эффективность программы. В приложениях, критичных ко времени, лучше использовать указатели. Если стоит вопрос об экономии памяти при обработке связанных списков, то вместо статически выделяемой памяти зачастую используется функция malloc(), динамически выделяющая память для структур. В следующей главе вы увидите, как это делается. В следующем примере показано, как структура передается в функцию целиком. Обратите внимание на то, что это — простая модификация предыдущего примера. В следующих четырех примерах используется та же самая идея. В каждой программе модифицируется только та часть алгоритма, которая необходима для прояснения конкретного вопроса. Такой подход позволит вам легко анализировать текст программ и изменения синтаксиса, необходимые для реализации конкретных возможностей языка. Просмотрите листинг программы и обратите внимание на то, как структура stused_boat передается в функцию vprint_data().

/* Программа на С, показывающая передачу структуры в функцию */

#include <stdio.h>

#define iSTRING15 15

#define iSTRING20 20

#define iNULL_CHAR 1

struct stboat {

char sztype [iSTRING15 + iNULL_CHAR];

char szmodel[iSTRING15 + iNULL_CHAR];

char sztitle[iSTRING20 + iNULL_CHAR];

int iyear;

long int lmotor_hours;

float fsaleprice;

};

void vprint_data(struct stboat stany_boat);

int main(void)

{

struct stboat stused_boat;

printf("\nPlease enter the type of the boat: ");

gets(stused_boat.sztype);

printf("\nPlease enter the model of the boat: ");

gets(stused_boat.szmodel);

printf("\nPlease enter the title number for the boat: ");

gets(stused_boat.sztitle);

printf("\nPlease enter the model year for the boat: ");

scanf("%d",&stused_boat.iyear);

printf("\nPlease enter the current hours on ");

printf("the motor for the boat: ");

scanf("%ld",&stused_boat.lmotor_hours);

printf("\nPlease enter the purchase price of the boat: ");

scanf("%f",&stused_boat.fsaleprice);

vprint_data(stused_boat);

return (0);

}

void vprint_data(struct stboat stany_boat)

{

printf("\n\n");

printf("A %d %s %s with title number #%s\n",stany_boat.iyear,

stany_boat.sztype,stany_boat.szmodel,stany_boat.sztitle);

printf("currently has %ld motor hours", stany_boat.lmotor_hours);

printf(" and was purchased for $%8.2f\n", stany_boat.fsaleprice);

}

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

  1. Массив структур. Описание массива структур. Определение элементов массива структур.

Часто структуры рассматриваются как массивы разнотипных данных.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]