Как вернуть структуру из функции c
Перейти к содержимому

Как вернуть структуру из функции c

  • автор:

Как вернуть структуру из функции c

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

Структура как параметр функции

При передаче структуры в качестве параметра получает копию значений структуры:

#include struct person < char* name; int age; >; void print_person(struct person user) < printf("Name: %s \n", user.name); printf("Age: %d \n", user.age); >int main(void) < struct person tom = ; print_person(tom); return 0; >

В данном случае функция print_person() принимает объект структуры person и выводит значения его элементов на консоль.

Чтобы не писать тип параметра полностью — struct person , можно определить псевдоним структуры:

#include typedef struct < char* name; int age; >person; void print_person(person user) < printf("Name: %s \n", user.name); printf("Age: %d \n", user.age); >int main(void) < person tom = ; print_person(tom); return 0; >

Указатели на структуру как параметры

При использовании структур в качестве параметров в функции следует учитывать, что при вызове функции для структуры, также как и для параметров типа int или char, выделяется память, в которую помещаются значения элементов структуры. То есть структура в функцию передается по значению, а это значит, что переданную в функцию структуру мы изменить не можем.

Если необходимо уменьшить выделение памяти (особенно если структура большая) или иметь возможность изменять изначальную структуру в функции, то можно передавать в функцию указатель на структуру:

#include struct person < char* name; int age; >; void change_person(struct person * user) < user->age = user->age + 1; > int main(void) < struct person bob = ; printf("Before change. %s : %d \n", bob.name, bob.age); change_person(&bob); printf("After change. %s : %d \n", bob.name, bob.age); return 0; >

В этом примере функция change_person принимает указатель на структуру person и увеличивает на единицу значение элемента age.

Для проверки в функции main выводим данные объекта person на консоль до и после вызова функции change_person.

Before change. Bob : 22 After change. Bob : 23

Структура как результат функции

Также функция может возвращать объект структуры:

#include struct person < char* name; int age; >; struct person create_person(char* name, int age) < struct person user; user.name = name; user.age = age; return user; >int main(void)

Здесь функция create_person() создает на основании полученных параметров объект структуры person и возвращает его в качестве результата.

Возврат структуры из функции в C++

Существует легенда, что возврат структуры по значению из функции в C++ — затратная процедура. Сегодня я займусь проверкой этой легенды.

Для этого пишу небольшой тестовый примерчик:

#include #include struct Object < public: int a; int b; int c; char string[50]; >; Object func() < Object o; o.a = 1; o.b = 2; o.c = 3; strcpy(o.string, "Hello world!"); return o; >int main(int argc, char ** argv)

Компилирую его c помощью gcc в моем случае. Тестирую, работает как положено выводит Hello world. Вторым шагом, чтобы проверить к чему приводит такой код, компилирую приведенный тестовый пример в ассемблер. gcc -S -c main.cpp

Что я вижу в ассеблерном коде:

.file "main.cpp" .section .rodata.str1.1,"aMS",@progbits,1 .LC0: .string "Hello world!" .text .p2align 1,0x90 .p2align 2,,3 .globl _Z4funcv .type _Z4funcv, @function _Z4funcv: .LFB3: pushl %ebp .LCFI0: movl %esp, %ebp .LCFI1: movl 8(%ebp), %eax pushl %edi .LCFI2: pushl %esi .LCFI3: cld movl $.LC0, %esi leal 12(%eax), %edi movl $3, %ecx movl $1, (%eax) movl $2, 4(%eax) movl $3, 8(%eax) rep movsl movsb popl %esi popl %edi leave ret $4 .LFE3: .size _Z4funcv, .-_Z4funcv .section .rodata.str1.1 .LC1: .string "%s" .text .p2align 1,0x90 .p2align 2,,3 .globl main .type main, @function main: .LFB4: pushl %ebp .LCFI4: movl %esp, %ebp .LCFI5: subl $72, %esp .LCFI6: andl $-16, %esp leal -72(%ebp), %eax subl $16, %esp pushl %eax .LCFI7: call _Z4funcv subl $8, %esp leal -60(%ebp), %eax pushl %eax pushl $.LC1 .LCFI8: call printf xorl %eax, %eax leave ret .LFE4: .size main, .-main .section .eh_frame,"a",@progbits .Lframe1: .long .LECIE1-.LSCIE1 .LSCIE1: .long 0x0 .byte 0x1 .string "zP" .uleb128 0x1 .sleb128 -4 .byte 0x8 .uleb128 0x5 .byte 0x0 .long __gxx_personality_v0 .byte 0xc .uleb128 0x4 .uleb128 0x4 .byte 0x88 .uleb128 0x1 .p2align 2 .LECIE1: .LSFDE3: .long .LEFDE3-.LASFDE3 .LASFDE3: .long .LASFDE3-.Lframe1 .long .LFB4 .long .LFE4-.LFB4 .uleb128 0x0 .byte 0x4 .long .LCFI4-.LFB4 .byte 0xe .uleb128 0x8 .byte 0x85 .uleb128 0x2 .byte 0x4 .long .LCFI5-.LCFI4 .byte 0xd .uleb128 0x5 .byte 0x4 .long .LCFI7-.LCFI5 .byte 0x2e .uleb128 0x4 .byte 0x4 .long .LCFI8-.LCFI7 .byte 0x2e .uleb128 0x10 .p2align 2 .LEFDE3: .ident "GCC: (GNU) 3.4.6 [FreeBSD] 20060305"

Что отсюда видно. Видно что в функции main() резервируется место в стеке под структуру Object o. А потом, как это не странно ссылка на эту выделенную память передается внутрь функции func(). И функция func не производя никакого выделения памяти самостоятельно, работает с полями структуры, предварительно загрузив адрес структуры в регистр eax.

Т.е. это означает, что никаких накладных расходов данный фрагмент не вызывает! Во первых нет ни одной операцией с «кучей». Всё выделяется в стеке вызывающей функции. Во-вторых адрес выделенной памяти передается скрытой ссылкой или указателем. Это как вам больше нравится. В ассеблере просто передается адрес.

Теперь проверим следующий, закономерный вопрос. А что если функция func сама является членом другого класса. Как компилятор поступит в этом случае. Провожу для этого второй эксперимент, аналогичный первому:

#include #include struct Object < int a; int b; int c; char s[50]; >; class A < int a; public: Object func(); >; Object A::func() < Object o; o.a=1; o.b=2; o.c=3; strcpy(o.s,"Hello world"); a=5; return o; >int main(int argc, char ** argv)

Аналогично, тестирую, затем компилирую в ассемблер:

.file "main1.cpp" .section .rodata .LC0: .string "Hello world" .text .p2align 1,0x90 .p2align 2,,3 .globl _ZN1A4funcEv .type _ZN1A4funcEv, @function _ZN1A4funcEv: .LFB3: pushl %ebp .LCFI0: movl %esp, %ebp .LCFI1: pushl %ebx .LCFI2: subl $4, %esp .LCFI3: movl 8(%ebp), %ebx movl $1, (%ebx) movl $2, 4(%ebx) movl $3, 8(%ebx) subl $8, %esp pushl $.LC0 leal 12(%ebx), %eax pushl %eax .LCFI4: call strcpy addl $16, %esp movl 12(%ebp), %eax movl $5, (%eax) movl %ebx, %eax movl -4(%ebp), %ebx leave ret $4 .LFE3: .size _ZN1A4funcEv, .-_ZN1A4funcEv .section .rodata .LC1: .string "%s" .text .p2align 1,0x90 .p2align 2,,3 .globl main .type main, @function main: .LFB4: pushl %ebp .LCFI5: movl %esp, %ebp .LCFI6: subl $88, %esp .LCFI7: andl $-16, %esp movl $0, %eax addl $15, %eax addl $15, %eax shrl $4, %eax sall $4, %eax subl %eax, %esp leal -88(%ebp), %edx subl $8, %esp leal -12(%ebp), %eax pushl %eax pushl %edx .LCFI8: call _ZN1A4funcEv addl $12, %esp subl $8, %esp leal -88(%ebp), %eax addl $12, %eax pushl %eax pushl $.LC1 call printf addl $16, %esp movl $0, %eax leave ret .LFE4: .size main, .-main .section .eh_frame,"a",@progbits .Lframe1: .long .LECIE1-.LSCIE1 .LSCIE1: .long 0x0 .byte 0x1 .string "zP" .uleb128 0x1 .sleb128 -4 .byte 0x8 .uleb128 0x5 .byte 0x0 .long __gxx_personality_v0 .byte 0xc .uleb128 0x4 .uleb128 0x4 .byte 0x88 .uleb128 0x1 .p2align 2 .LECIE1: .LSFDE1: .long .LEFDE1-.LASFDE1 .LASFDE1: .long .LASFDE1-.Lframe1 .long .LFB3 .long .LFE3-.LFB3 .uleb128 0x0 .byte 0x4 .long .LCFI0-.LFB3 .byte 0xe .uleb128 0x8 .byte 0x85 .uleb128 0x2 .byte 0x4 .long .LCFI1-.LCFI0 .byte 0xd .uleb128 0x5 .byte 0x4 .long .LCFI3-.LCFI1 .byte 0x83 .uleb128 0x3 .byte 0x4 .long .LCFI4-.LCFI3 .byte 0x2e .uleb128 0x10 .p2align 2 .LEFDE1: .LSFDE3: .long .LEFDE3-.LASFDE3 .LASFDE3: .long .LASFDE3-.Lframe1 .long .LFB4 .long .LFE4-.LFB4 .uleb128 0x0 .byte 0x4 .long .LCFI5-.LFB4 .byte 0xe .uleb128 0x8 .byte 0x85 .uleb128 0x2 .byte 0x4 .long .LCFI6-.LCFI5 .byte 0xd .uleb128 0x5 .byte 0x4 .long .LCFI8-.LCFI6 .byte 0x2e .uleb128 0x10 .p2align 2 .LEFDE3: .ident "GCC: (GNU) 3.4.6 [FreeBSD] 20060305"

Этот код показывает, что опять в функцию func() в качестве первого аргумента передается указатель на структуру Object o. Функция в данном случае загружает его адрес в регистр ebx и заполняет поля структуры. Затем загружает в регистр eax второй скрытый параметр, содержащий указатель на экземпляр класса, которому принадлежит функция, т.е. this.

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

Передача структур в функции и возврат структур из функций

Замечаем, что функция main выделяет в стеке 16 байт, но при выравнивании стека освобождаются только 8 байт. Остальные 8 байт заняты структурой. Функция makepoint :

 0x080483bb : push ebp 0x080483bc : mov ebp,esp 0x080483be : sub esp,0x10 0x080483c1 : mov eax,DWORD PTR [ebp+0xc] 0x080483c4 : mov DWORD PTR [ebp-0x8],eax 0x080483c7 : mov eax,DWORD PTR [ebp+0x10] 0x080483ca : mov DWORD PTR [ebp-0x4],eax 0x080483cd : mov ecx,DWORD PTR [ebp+0x8] 0x080483d0 : mov eax,DWORD PTR [ebp-0x8] 0x080483d3 : mov edx,DWORD PTR [ebp-0x4] 0x080483d6 : mov DWORD PTR [ecx],eax 0x080483d8 : mov DWORD PTR [ecx+0x4],edx 0x080483db : mov eax,DWORD PTR [ebp+0x8] 0x080483de : leave 0x080483df : ret 0x4 

Еще раз посмотрим на это место в main :

 0x080483eb : push 0x2 0x080483ed : push 0x1 0x080483ef : push eax 0x080483f0 : call 0x80483bb

С учетом адреса возврата и сохраненного ebp , адрес структуры (push eax) будет отодвинут на 3 дворда, это 0xC байт, и, видимо, обращение к адресу структуры мы наблюдаем здесь:

mov eax,DWORD PTR [ebp+0xc] 

А что происходит дальше в makepoint ? Сложно разобраться в этом коде. В общем, я так понимаю: когда функция передает структуру другой функции, или когда другая функция возвращает структуру, вызывающая функция сама выделяет место для этой структуры. Потом передает только адрес этой структуры скрытым параметром. Еще есть такая штука как выравнивание полей структуры. Можно это понаблюдать в листинге? С чем связано это выравнивание?

C++. Структуры. Часть 4. Структуры и функции. Передача структуры в функцию в среде CLR. Возврат структуры из функции

Структуры. Часть 4. Структуры и функции. Передача структуры в функцию в среде CLR . Возврат структуры из функции

Поиск на других ресурсах:

1. Какие существуют способы передачи структуры в функцию?

Существует 2 способа передачи native -структуры в функцию в качестве параметра:

  • передача структуры по значению. При такой передаче делается копия структурной переменной в памяти. Если структура имеет большой размер, то такой способ неэффективен. Преимуществом этого способа есть то, что все манипуляции с копией структуры в функции не влияют на исходную переменную;
  • передача указателя на структуру. В этом случае передается только указатель на структуру а не вся структура. Если структура занимает большой объем памяти, то такой способ обеспечивает быструю передачу значений структурной переменной в функцию. Это связано с тем, что передается только указатель на структуру. Недостатком этого способа есть то, что в функции случайно можно изменить значения исходной структурной переменной, в тех случаях когда это нежелательно.
2. Какие есть способы возврата структуры из функции?

Так же, как и при передаче структуры в функцию (см. п.1), существуют 2 способа возврата:

  • возврат структуры по значению;
  • возврат указателя на структуру.

Преимущества и недостатки каждого способа такие же, как описано в п. 1.

3. Пример передачи native -структуры в функцию по значению

Пусть в модуле «MyStruct.h» даны объявления native -структуры:

// native-структура, которая описывает точку на координатной плоскости struct MyPoint < int x; int y; >;

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

// функция, которая сравнивает на равенство две точки public: bool EqualPoints(MyPoint p1, MyPoint p2) < bool f = false; if ((p1.x == p2.x) && (p1.y == p2.y)) f = true; return f; >

Тогда использование функции EqualPoints() может быть следующим:

// подключение модуля "MyStruct.h" #include "MyStruct.h" . // передача native-структуры в функцию по значению bool f_equal; MyPoint pt1, pt2; // p1, p2 – переменные типа "структура" // заполнение значениями pt1.x = 23; pt1.y = 35; pt2.x = 23; pt2.y = 35; f_equal = this->EqualPoints(pt1, pt2); // f_equal = true pt1.x = 100; f_equal = EqualPoints(pt1, pt2);
4. Пример передачи native -структуры в функцию по указателю

Пусть задана native -структура:

// native-структура struct MyPoint < int x; int y; >;

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

// передача указателя на структуру MyPoint bool EqualPointsP(MyPoint * p1, MyPoint * p2) < bool f = false; if ((p1->x == p2->x) && (p1->y == p2->y)) f = true; return f; >

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

// Передача структуры по указателю MyPoint p1; MyPoint p2; bool f_equal; p1.x = 28; p1.y = 35; p2.x = 28; p2.y = 35; f_equal = EqualPointsP(&p1, &p2); // f_equal = true p2.y = 100; f_equal = EqualPointsP(&p1, &p2); // f_equal = false
5. Как передать в функцию managed -структуру, которая объявлена с квалификатором ref ? Пример

Пусть задана следующая ref -структура.

// ref-структура ref struct MyPointRef < int x; int y; >;

Структуры с квалификатором ref есть структурами ссылочного типа. Для таких структур память должна выделяться с помощью утилиты gcnew . Поэтому, в функцию можно передать только ссылку на такие структуры.

Пусть дана функция LengthRef() , которая определяет длину линии, которая соединяет 2 точки. Функция получает две ref -структуры в качестве параметров.

// Функция, определяющая длину между двумя точками float LengthRef(MyPointRef ^p1, MyPointRef ^p2) < float l; l = Math::Sqrt((p1->x-p2->x)*(p1->x-p2->x) + (p1->y-p2->y)*(p1->y-p2->y)); return l; >

Использование функции LengthRef() в некотором программном коде.

// передача ref-структуры в функцию MyPointRef ^ pt1; MyPointRef ^ pt2; float len; // выделение памяти для ref-структур pt1 = gcnew MyPointRef; pt2 = gcnew MyPointRef; // заполнение ref-структур значениями pt1->x = 35; pt1->y = 35; pt2->x = 40; pt2->y = 40; len = LengthRef(pt1, pt2); // len = 7.071068
6. Как передать в функцию managed -структуру, которая объявлена с квалификатором value ? Пример

Managed -структуру, объявленную с квалификатором value можно передать в функцию одним из двух способов:

  • по значению;
  • по указателю.

Ниже приведены оба способа для value -структуры MyPointValue , которая имеет следующее объявление.

// value-структура value struct MyPointValue < int x; int y; >;

Способ 1.

Пусть задана функция LengthValue() , определяющая расстояние между двумя точками. Функция получает входным параметром две структуры типа MyPointValue . Структуры передаются как параметр-значение.

// определение расстояния между двумя точками float LengthValue(MyPointValue p1, MyPointValue p2) < float len; len = (float)Math::Sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)); return len; >

Пример использования функции LengthValue() в другом программном коде.

// передача value-структуры по значению MyPointValue pt1; MyPointValue pt2; float len; pt1.x = 35; pt1.y = 50; pt2.x = 40; pt2.y = 55; len = LengthValue(pt1, pt2); // len = 7.071068

Способ 2. Передача структуры по указателю.

Пусть задана функция LengthValue() , получающая два указателя на структуры типа MyPointValue .

// функция получает указатель на value-структуру float LengthValueP(MyPointValue *p1, MyPointValue *p2) < float len; len = Math::Sqrt((p1->x-p2->x)*(p1->x-p2->x) + (p1->y-p2->y)*(p1->y-p2->y)); return len; >

Использование функции LengthValue() в программе.

// передача value-структуры по указателю MyPointValue pt1; MyPointValue pt2; float len; pt1.x = 0; pt1.y = 0; pt2.x = 10; pt2.y = 10; len = LengthValueP(&pt1, &pt2); // len = 14.14214
7. Как реализовать возврат экземпляра native -структуры из функции? Пример

Возвратить native -структуру можно:

  • по значению;
  • по адресу.

Пусть задана структура MyPoint

// native-структура struct MyPoint < int x; int y; >;

Пусть в программе реализована функция GetCenterLine() , которая вычисляет координаты середины отрезка, соединяющего 2 точки. Функция получает 2 параметра – координаты концов отрезка.

// функция, возвращающая native-структуру // функция вычисляет координаты середины отрезка MyPoint GetCenterLine(MyPoint p1, MyPoint p2) < MyPoint res; res.x = (p1.x + p2.x)/2; res.y = (p1.y + p2.y)/2; return res; >

Демонстрация возврата native -структуры по значению.

MyPoint pt1; MyPoint pt2; MyPoint res; // результат, память уже выделена pt1.x = 30; pt1.y = 20; pt2.x = 36; pt2.y = 40; res = GetCenterLine(pt1, pt2); // res - координаты середины отрезка
8. Пример возврата из функции указателя на native -структуру

Пусть задана структура MyPoint

// native-структура struct MyPoint < int x; int y; >;

Пусть реализована функция GetCenterLine() , которая получает 2 точки и возвращает указатель на структуру. В теле функции реализовано выделение памяти для структуры оператором new .

MyPoint * GetCenterLine(MyPoint p1, MyPoint p2) < MyPoint * res; // указатель на структуру MyPoint // выделение памяти для структуры res = new MyPoint; // вычисление середины отрезка - заполнение значениями resP->x = (p1.x + p2.x)/2; resP->y = (p1.y + p2.y)/2; return res; >

Демонстрация работы с функцией GetCenterLine() .

// возвращение native-структуры по указателю MyPoint * resPt; // указатель на структуру – память для структуры еще не выделена MyPoint pt1, pt2; // экземпляры структуры pt1.x = 28; pt1.y = 40; pt2.x = 38; pt2.y = 50; // вызов функции GetCenterLine() // для указателя resPt память выделяется внутри функции resPt = GetCenterLine(pt1, pt2); // проверка int d; d = resPt->x; // d = 33 d = resPt->y; // d = 45
9. Как возвратить экземпляр value -структуры из функции?

Если в среде CLR описана структура с квалификатором value , то возврат экземпляра такой структуры из функции ничем не отличается от возвращения native -структуры (см. п. 7.).

10. Пример возврата указателя ( ^ ) на value -структуру

Если структура объявлена с квалификатором value , то функция может возвращать указатель на эту структуру. Допускается использование двух видов указателей:

  • классического указателя, который обозначается символом ‘*’ . Возврат такого указателя из функции не отличается от возврата указателя на native -структуру (см. п. 8);
  • указателя, предназначенного для работы с объектами среды CLR . Такой указатель обозначается символом ‘^‘ . Память для такого указателя выделяется утилитой gcnew . Ниже приведен пример возврата из функции такого указателя на value -структуру.

Пусть объявлена структура с квалификатором value

// value-структура value struct MyPointValue < int x; int y; >;

Пусть нужно реализовать функцию GetCenterLineVP() , которая получает 2 точки и возвращает указатель на результирующую value -структуру. Результирующая структура содержит координаты центра отрезка, который соединяет точки. Функция имеет следующий вид:

// функция возвращает указатель на value-структуру MyPointValue ^ GetCenterLineVP(MyPointValue p1, MyPointValue p2) < MyPointValue ^ pv; // указатель на структуру MyPointValue pv = gcnew MyPointValue; pv->x = (p1.x + p2.x)/2; pv->y = (p1.y + p2.y)/2; return pv; >

Демонстрация вызова функции из другого программного кода:

// создание экземпляров структур с инициализацией MyPointValue pt1 = < 20, 30 >; MyPointValue pt2 = < 40, 60 >; // указатель на структуру MyPointValue MyPointValue ^ resPt; // вызов функции GetCenterLineVP() // внутри функции выделяется память для структуры, // на которую указывает resPt resPt = GetCenterLineVP(pt1, pt2); // проверка int d; d = resPt->x; // d = 30 d = resPt->y; // d = 45
11. Пример возврата из функции структуры, которая объявлена с квалификатором ref

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

Пусть объявлена структура

// ref-структура ref struct MyPointRef < int x; int y; >;

Тогда функция, которая получает 2 точки в качестве параметров и находит центр между двумя точками будет иметь приблизительно следующий вид:

// функция, возвращающая ref-структуру MyPointRef ^ GetCenterLineRef(MyPointRef ^p1, MyPointRef ^p2) < MyPointRef ^resPt; // выделение памяти для указателя resPt resPt = gcnew MyPointRef; // заполнение значениями полей указателя resPt->x = (p1->x + p2->x)/2; resPt->y = (p1->y + p2->y)/2; return resPt; >

Демонстрация использования функции в другом программном коде.

// указатели на ref-структуру MyPointRef ^pt1; MyPointRef ^pt2; MyPointRef ^resPt; // выделение памяти для указателей pt1, pt2 pt1 = gcnew MyPointRef; pt2 = gcnew MyPointRef; // заполнение значениями pt1->x = 20; pt1->y = 20; pt2->x = 30; pt2->y = 40; // вызов функции GetCenterLineRef() // память для указателя resPt выделяется внутри функции resPt = GetCenterLineRef(pt1, pt2); // проверка int d; d = resPt->x; // d = 25 d = resPt->y; // d = 30

Связанные темы

  • Структуры. Часть 1. Составные типы данных. Шаблон структуры. Структурная переменная. Структуры в среде CLR. Объявление и инициализация структурной переменной
  • Структуры. Часть 2. Выделение памяти для структуры. Вложенные структуры. Массивы native-структур
  • Структуры. Часть 3. Работа с managed-структурами в среде CLR. Квалификаторы ref и value. Объявление структурных переменных. Массивы managed-структурных переменных. Инициализация managed-структур
  • Функции. Часть 1. Описание функции. Фактические и формальные параметры. Передача параметров в функцию по значению и по адресу. Прототип функции
  • Функции. Часть 2. Функции и массивы. Передача одномерного и многомерного массива в функцию. Передача структуры и класса в функцию

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *