Могу ли я передавать массивы функциям так же, как Я бы сделал с примитивами типа int and bool?
Да, но только с использованием указателей (то есть по ссылке).
Могу ли я передать их по значению?
Нет. Вы можете создавать классы, поддерживающие это, но простые массивы - нет.
Как функция узнает размер переданного массива?
Не знает. Это причина использовать такие вещи, как vector
вместо T *
.
Пояснение
Функция может принимать ссылку или указатель на массив определенного размера:
void func(char (*p)[13])
{
for (int n = 0; n < 13; ++n)
printf("%c", (*p)[n]);
}
int main()
{
char a[13] = "hello, world";
func(&a);
char b[5] = "oops";
// next line won't compile
// func(&b);
return 0;
}
Я почти уверен, что это не то, что искал OP.
Вы можете передавать массивы обычным способом, как это делает C (массивы разлагаются на указатели), или вы можете передавать их по ссылке, но они не могут быть переданы по значению. Во втором случае они переносят свой размер вместе с собой:
template <std::size_t size>
void fun( int (&arr)[size] )
{
for(std::size_t i = 0; i < size; ++i) /* do something with arr[i] */ ;
}
В большинстве случаев использование std::vector
или другой последовательности из стандартной библиотеки более элегантно, если только вам не нужны специально собственные массивы.
Вы можете передавать std::vector
и подобные хорошо спроектированные объекты по значению (хотя это довольно редкое явление). Обычно вы передаете по ссылке или const ссылке.
Массив в C/C++, как в
void foo(int x[])
всегда передается по ссылке. Кроме того, функция не может определить истинный размер аргумента, переданного вызывающей стороной, вы должны предположить размер (или передать его как отдельный параметр).
Могу ли я передавать массивы в функции так же, как как это делается с такими примитивами, как int и bool?
Да, можно. При передаче имени массива в качестве аргумента функции передается адрес первого элемента.
Короче говоря:
void foo(int a[]);
эквивалентно
void foo(int * a);
Могу ли я передавать их по значению?
Не совсем. "Значение", которое передается с именем массива, - это адрес первого элемента.
Единственный способ передать копию массива в стиле C - это обернуть его в class
или struct
, реализующий семантику глубокого копирования.
Как функция узнает о размере переданного ей массива?
Никак, если только ваша функция не принимает дополнительный параметр, который является размером массива.
Массивы в стиле C ведут себя очень странно при передаче в функции. Для массивов фиксированного размера я бы рекомендовал вместо этого std :: array
, который можно передавать по значению, как встроенные типы. Для массивов переменного размера я рекомендую std :: vector
, как предлагается в других ответах.
void f (int a []);
и назовите его так: int myArr [size]; f (myArr);
Да, вы можете передавать их так же, как примитивные типы. Да, вы можете передавать по значению, если действительно хотите, с помощью некоторого кода оболочки, но вам, вероятно, не следует этого делать. В качестве длины он будет принимать размер прототипа функции, который может совпадать или не совпадать с входящими данными, поэтому на самом деле он не знает.
Или!
Передайте ссылку или константную ссылку на вектор, чтобы быть безопаснее, и информация о размере будет у вас под рукой.
Вы можете передать массив, но вы должны передать размер вместе с ним, если хотите знать его наверняка:
function(array, size);
Массивы всегда передаются по ссылке, и функцию можно записать одним из двух способов:
Declaration: void function (class*, int);
Implementation: void function(class array[]; int size) {}
или
Declaration: void function (class*, int);
Implementation: void function(class *array; int size) {}
Когда вы передаете массив функции, функция, по сути, получает указатель на этот массив, как показано во втором примере выше. Оба примера приведут к одному и тому же.