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

При передаче структур функциям, как будет выглядеть прототип/заголовок? Как они будут выглядеть при передаче членов структур в функции?

Например...

struct a_struct{
int a;
int b;
};

a_struct point;

void f1(a_struct)
void f2(a_struct)

И допустим, что я хочу передать всю структуру в f1, а только член в f2. Буду ли я использовать тип данных a_struct в качестве параметра для обоих? Или f2 будет иметь другой тип данных, потому что я передаю только член, который является int. Будет ли это меняться для массива структур? Программа, которую мне поручили написать, должна использовать массивы структур. Я подумал, что это не будет иметь большого значения, за исключением того, что оно будет автоматически передано по ссылке.


person user1768079    schedule 29.11.2012    source источник
comment
У меня есть книга, и я внимательно просмотрел ее, а также поискал в Интернете. В книге описаны основы использования структур, в ней нет ничего, что явно говорило бы о том, как они передаются функциям. И хотя я нашел кое-что из этого в Интернете, я ничего не нашел о передаче массивов структур.   -  person user1768079    schedule 29.11.2012
comment
structures — это обычные типы и обычные параметры. Как только вы поймете основы и как использовать функции и их параметры, вы найдете ответ на свой вопрос. Вы не можете просто так пройтись по книге.   -  person Kiril Kirov    schedule 29.11.2012


Ответы (4)


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

Возможное объявление для вас может быть:

void f1(a_struct& my_struct);

Это передаст ссылку на объект a_struct и предотвратит любое копирование объекта. Однако структура вашего примера содержит только скалярные значения, так что возможность копирования объекта не вызывает особого беспокойства. В результате этого будет достаточно:

void f1(a_struct my_struct);

Что касается передачи члена структуры в функцию, функция должна быть объявлена ​​так, чтобы она принимала тип члена. Например, чтобы передать член a_struct в функцию, вы должны сделать:

void f1(int val);

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

void f1(a_struct* my_struct);

Однако затем вы можете просто ссылаться на параметр в обычном режиме. Например:

my_structs[1];
person ScoPi    schedule 29.11.2012
comment
Здесь я исправил вопиющие синтаксические ошибки: struct — это ключевое слово, поэтому вы не можете использовать его в качестве идентификатора. - person underscore_d; 15.12.2017

Чтобы f1 взял a_struct, это зависит от того, хотите ли вы иметь возможность редактировать его в f1. void f1(a_struct s); будет работать нормально и сделает копию. void f1(const a_struct & s); принимает ссылку, но вы не можете изменить ее (во всяком случае, без каких-либо хлопот). Я стараюсь избегать ссылок, отличных от const.

Если вы хотите, чтобы f2 получил int, напишите void f2(int);. Неважно, откуда взялся этот int (то есть внутри struct или сам по себе). Затем назовите его как f2(point.b);

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

void f3 (a_struct * const structArray)
{ /* Do something */ }
a_struct myArray[10];
f3(myArray);

Есть и другие (лучшие) способы сделать это.

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

a_struct myArray[10];
for (int i = 0; i < 10; ++i)
{
    f1( myArray[i] );
}

// Or, better, from <algorithm>
std::for_each(myArray, myArray+10, f1);

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

Конечно, все это предполагает, что вам действительно нужен массив, а не std::vector. (в этом случае циклы выглядят в основном одинаково, за исключением того, что вы будете использовать функции-члены begin() и end()).

На самом деле, если у вас есть доступ к c++11, вы можете использовать std::begin() и std::end(), который будет работать точно так же для vectors или массивов.

person BoBTFish    schedule 29.11.2012
comment
Спасибо за быстрый ответ. Это то, что я понял. Если я передам определенное место в массиве, например, у меня есть, и я хочу передать все объекты функции 1 на 1, используя цикл... a_struct object[5]; f1(object[], i) или просто пройти как f1(object[i]) - person user1768079; 29.11.2012

Когда вы хотите передать структуру (или класс):

return_type fn_name(object_name)

Если вы хотите передать один из его членов, скажем, a в этом случае.

return_type fn_name(int)

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

person ApplePie    schedule 29.11.2012

если вы хотите передать значение только функции-члена, отправьте ее тип, например, функция, которая принимает «a» a_struct в качестве параметра, должна быть void func (int a);

но он будет работать для вызова по значению. Если вы хотите использовать вызов как ссылку, используйте указатель.

person Debobroto Das    schedule 29.11.2012