Здесь, в f(), я принимаю массив с максимальным размером 4, но он по-прежнему работает нормально, когда я передаю массив размером больше 4 (здесь 10), я знаю, что массивы в С++ по умолчанию передаются как указатели, но когда это метод передачи массива полезен?
#include<iostream>
using namespace std;
void f(int a[4]){
for(int i = 0;i < 3;i++){
a[i] += 10;
}
}
int main(){
int a[10];
for(int i = 0;i < 10;i++)
a[i] = i;
f(a);
for(int i =0 ;i < 10;i++){
cout<<a[i]<<" ";
}
cout<<"\n";
return 0;
}
выход: 10 11 12 3 4 5 6 7 8 9
Это проклятие массивов C. Вы не можете поместить их в параметры функции или вернуть их. Вам нужно найти какой-то обходной путь использования указателя или ссылки на массив или вставки массива в структуру (что и есть std::array).
Я просто хотел знать, почему этот метод приема массива в С++ используется
«почему этот метод приема массива в С++ используется» для совместимости с C
Я слышал, что причина в том, что в раннем C передача массива по значению была немыслима и, безусловно, была ошибка производительности. Поэтому они решили незаметно исправить вашу ошибку производительности, превратив массив в указатель.
Хорошо понял, это означает, что этот метод не имеет никакого значения в c++@nwp
Я предлагаю вам избегать массивов C, насколько это возможно. Обычно, но не всегда, std::array лучше.
@nwp Путаница «массивы - это указатели» восходит к BCPL (от которого C происходит через B). В этот момент массивы указателей мы. Объявление переменной как массива выделяло где-то указанное количество слов (я помню, была ли это куча или стек) и инициализировало переменную их адресом. Так что «не может передавать массивы по значению» действительно очень старый.





Если вы хотите наложить ограничения на размер передаваемого массива, вы можете перейти на передачу по ссылке.
void f(int (&a)[4]){
for(int i = 0;i < 3;i++){
a[i] += 10;
}
}
void f(int a[4]) такое же, как void f(int* a); это означает, что вы можете передать массив любого размера, который будет распадаться на указатель (т.е. int*) при передаче.
Либо сделайте f() более строгим, как показано @songyuanyao, либо рассмотрите возможность использования C++ std::array вместо этого:
#include <iostream>
#include <array>
// make an alias for the array you'd like to accept
using myarray_t = std::array<int, 4>;
// accept the array by reference
void f(myarray_t& a) {
// use a range based for loop to access elements by reference
for(int& a_i : a) a_i += 10;
}
int main() {
// declare your array
myarray_t a;
for(size_t i = 0; i < a.size(); ++i) a[i] = static_cast<int>(i);
f(a);
// and you can use a range based for loop to extract by value too
for(int a__i : a)
std::cout << a_i << " ";
std::cout << "\n";
return 0;
}
I know arrays in c++ are passed as pointers by default
Правильный.
Этот:
void foo(int a[4])
буквально переписывается так:
void foo(int* a)
… и затем, когда вы вызываете функцию, имя вашего массива распадается на указатель, соответствующий переписанному/«настоящему» типу аргумента.
Таким образом, вы вообще не передаете массив.
When is this method of passing array useful?
Никогда.
Это позорная странность, унаследованная от C. Можно возразить, что [4] — это полезный намек разработчику на то, что массив, на который указывает указатель, «должен» иметь четыре элемента, но современная мудрость состоит в том, что это просто излишне и опасно вводит в заблуждение.
Лучшие альтернативы включают в себя:
std::array<int, 4> (по ссылке): как выше, но аккуратнееИли переключитесь на std::vector вместо массива — это почти всегда мое первое предложение.
@MartinBonner Вероятно, это излишество для четырех int, но стоит подумать, что если вам нужно хранилище с изменяемым размером (если нет, на самом деле нет причин предпочитать vectorarray)
Вместо этого используйте
std::arrayилиstd::vector