Процедурное программирование на языке С. Часть 3. Файлы и структуры: Методические указания к лабораторным работам по курсам «Алгоритмические языки и программирование» и «Процедурное программирование», страница 15

   pp= (struct person*)malloc(sizeof(struct person));

   pp->str=(char *) malloc(10* sizeof(char));    strcpy(pp->str,"Sidorov");

   printf("\n Vvod: amount of months = ");      scanf("%d",  &pp->n);

   pp->wages=(float *) malloc(pp->n * sizeof(float));    

  for(i=0 ;  i < pp->n;  i++)        

     {printf("\n Vvod: wages of months N %d= ", i);

       scanf("%f",pp->wages+i);   }

   printf("\n N = %d  ",pp->n);       printf("  fio: %s  ",pp->str);

   for(i=0;i<pp->n; i++) 

        printf("\n wages of months N %d= %f ", i, pp->wages[i]);

}

При работе программы примера 7.12  в 16-ти разрядной среде выделяется 4 участка памяти:

·  2 байта для переменной pp;

·  6 байт  для значений полей структуры (по 2 байта для каждого поля), причем адрес первого из этих 6-ти байт – значение переменной pp;

·  10 байт  для символьного массива, причем адрес первого из этих 10-ти байт – значение первого поля структуры;

·  после ввода значения во второе поле структуры (pp->n) выделяется pp->n*4  байт  для данных о зарплате сотрудника за каждый из отработанных месяцев, причем адрес первого из этих  байт – значение третьего поля структуры.

7.6. ПЕРЕДАЧА СТРУКТУР ФУНКЦИЯМ

В случае, когда в функцию передается значение  какого-либо элемента структуры, формальный параметр функции должен иметь тот же тип, что и соответствующий элемент структуры. При этом не имеет значения то, что аргумент функции при вызове взят из совокупности значений –  из структуры. В таблице 7.1 приведены примеры вызовов и заголовков функций, аргументами которых являются значения элементов структуры PR типа structperson :

struct person

       { int tab_num;      char str[20];    char pol;

         float * wages;      float average; } PR ;

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

Таблица 7.1.

Вызов функции

Тип формального параметра

Заголовок функции

f1(PR. tab_num);

int :  аргумент – целое число

void f1(int  n)

f2(PR.str);

char * :  аргумент – адрес строки

void f2 (char *st)

f3(pol);

char :  аргумент – символ

void f3 (char sim)

f4(PR.wages);

float * :  аргумент – адрес переменной типа float

void f4 (float *wg)

f4(PR.average);

float: аргумент – переменная типа float

void f4 (float wg)

Если необходимо передать адрес отдельного элемента структуры, то в операции доступа к элементу перед именем структуры (а не перед именем элемента) должен находится оператор ‘&’.

Например, передача адреса первого элемента структуры осуществляется при вызове функции f5(&PR. tab_num); –  заголовок которой должен иметь вид: voidf5(int * n).

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

·  аргумент второй функции   – адрес структуры;

·  структура – возвращаемое значение второй функции.

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