Передача полей структуры в функцию.

Пусть заголовок некоторой функции имеет следующий вид:

void MyFun1 (int x, float &y, int *u1, float *u2, char *S);

В вызывающей функции пусть объявлен тот же структурный тип и переменная этого типа:

struct tst { char *t; int m;

float *ard; float per;

int *p; } S1;

Тогда при вызове такой функции в качестве фактического параметра можно передать поле целого типа из структуры S1 (S1.m), поле вещественного типа (S1.per). При передаче полей-указателей перед вызовом функции их надо проинициализировать одним из указанных ранее способов. При этом если в функции переменная u1 используется как адрес простой вещественной переменной, а не массива, то должны, например, записать S1.p=new int. Пусть из текста функции видно, что и2 —динамический массив, так как используется в функции индексирование (u2[i]). Тогда перед её вызовом должны создать динамический массив, например, так:

S1.ard=new float[S1.m].

Аналогично должны зарезервировать память и для передаваемой строки:

S1.t=new char [20].

Тогда вызвать функцию можно, например, так:

MyFun1(S1.m, S1.per, S1.p, S1.ard, S1.t);

или

MyFun1(S1.m, S1.per, S1.p, &(S1.ard[0]), S1.t);

Но возможны и другие варианты передачи полей структуры в функцию MyFun1 . Например, для формального параметра x можно в качестве фактического с помощью операции разыменования передать значение ячейки, адрес которой хранится в поле p структуры, а для y — один 0-й элемент массива S1.ard. Наоборот, адрес какого-нибудь поля простого типа (например, m) может быть передан для параметра u1:

MyFun1(*(S1.p), S1.ard[0], &(S1.m), …);

Заметим, что операция “разыменования” (*) использована, так как поле p в структуре содержит адрес, а параметр x в функции не является указателем. Наоборот, записали операцию “взятие адреса” (&), так как параметр u1 в функции является указателем, а элементструктуры m содержит вещественное число, а не адрес. И, наконец, для одного элемента массива ни операция “разыменования” (*), ни “взятие адреса” не нужны, так как и параметр y в функции, и элемент массива S1.ard[0] ввызывающей программе не являются указателями. Но для u2 передать S1.ard[0] нельзя, так как u2 — это адрес.

Пусть в вызывающей функции объявлен указатель на структуру и зарезервирована память для неё:

tst *pS; pS= new tst;

Тогда допустимы, например, такие вызовы:

MyFun1(pS->m, pS->per, pS->p, pS->ard, pS->t…);

MyFun1(*( pS->p), pS->ard[0], &( pS->m), …);

Аналогично можно в функцию передать поля i– го элемента предварительно созданного динамического массива структур:

MyFun1(arSd[i].m, arSd[i].per, arSd[i].p, arSd[i].ard, arSd[i].t…);

MyFun1(*(arSd[i].p), arSd[i].ard[0], &( arSd[i].m), …);

Ещё раз заметим, что использовали операцию “.” (“точка”), а не “->”(“стрелка”), так как arSd содержит адрес начала динамического массива структур, а его элемент arSd[i] не является указателем.

Всё вышесказанное можно “собрать” вместе:

Пример .

void MyFun1 (int x, float &y, int *u1, float *u2, char *S)

{ y=x+1;

cout<<endl<<x<<" "<<y<<" "<<(*u1)<<" "<<(*u2)<<" "<<S;

};

void main()

{ struct tst { char *t; int m;

float *ard; float per;

int *p;

} S1;

S1.m=4;

S1.p=new int (5);

S1.ard=new float[S1.m]; S1.ard[0]=100;

S1.t=new char [20]; strcpy(S1.t,"Testing");

MyFun1(S1.m, S1.per, S1.p, S1.ard, S1.t); //или

//MyFun1(S1.m, S1.per, S1.p, &(S1.ard[0]), S1.t);

tst *pS=new tst;

pS->m=4;

pS->p=new int (5);

pS->ard=new float[pS->m]; pS->ard[0]=100;

pS->t=new char [20]; strcpy(pS->t,"Testing");

MyFun1(pS->m, pS->per, pS->p, pS->ard, pS->t);

tst *arSd;

arSd =new tst[3] ;

arSd [0].m=4;

arSd [0].p=new int (5);

arSd [0].ard=new float[arSd [0].m]; arSd [0].ard[0]=100;

arSd [0].t=new char [20]; strcpy(arSd [0].t,"Testing");

MyFun1(arSd [0].m, arSd [0].per, arSd [0].p, arSd [0].ard, arSd [0].t);

getch();

}