#cpp #code_style
void foo(int mass[]);
void foo(int *pMass);
Как принято делать?
Ответы
Ответ 1
Запись void foo(int mass[/*сколько-то*/]);//параметр имеет тип int*, а не int[/*сколько-то*/] полностью аналогична записи void foo(int *pMass); по своему функционалу. Никакой передачи массива в данном случае нет. В обоих случаях передается указатель. Это просто еще одна форма записи одного и того же. Лично мне более привычен второй вариант, как минимум потому что он более очевидный.Ответ 2
В языке С синтаксис массива отличается от синтаксиса указателя в том, что язык требует, чтобы типа элемента массива был полным (complete). Также, если в [] указан размер массива, то язык требует положительности этого размера. На указательный синтаксис такие ограничения не накладываются. (В языке С++ существует только второе требование). Также в языке С, пользуясь синтаксисом массива, у вас есть возможность делать объявления вида void foo(int array[static 10]) Синтаксис указателя аналогичной возможности не предоставляет. (К С++ не относится) Эти факторы могут служить объективными предпосылками для выбора того или иного синтаксиса. В остальном оба варианта синтаксиса эквивалентны и вопрос выбора является вопросом персональных предпочтений. При работе с массивами, я лично использую указательный синтаксис тогда, когда передаваемый указатель имеет семантику "итератора", и массивный синтаксис, когда речь идет о передаче ("по указателю") собственно всего массива. Хотя и тут границы размыты.Ответ 3
В стандарте вообще есть указатель на массив неопределённого размера. Можно указывать переменную этого типа. Возвращать указатель на массив. Но почему-то запрещается передавать указатель на безразмерный массив как аргумент функции. typedef int ( & vararray ) [ ] ; vararray f ( void ) { int array5 [ 5 ] ; int array10 [ 10 ] ; int ( * pointer_to_array ) [ ] = (int(*)[])& array5 ; pointer_to_array = (int(*)[])& array10 ; pointer_to_array = (int(*)[])new int [ 20 ] ; ( * pointer_to_array ) [ 10 ] = 777 ; return *pointer_to_array ; } Есть вариант упаковать этот указатель в структуру или класс. Тогда можно передавать указатель как аргумент. // g++ -std=c++11 -Wall pointertoarray2.cpp # includeusing std::cout; using std::endl; template < class T > class arrlnk { public : arrlnk ( void ) : a { nullptr } { } arrlnk ( T * const x ) : a { (T (&)[])*x } { } T & operator [] (size_t i) { return a[i] ; } private : T ( & a ) [ ] ; } ; void g(arrlnk a) { cout<<"a[10]="< array_link = f ( ) ; cout <<"array_link [ 10 ]="<< array_link [ 10 ]< Ответ 4
Передавать два итератора - на начало и на конец обрабатываемого диапазона. Это позволяет отвязать логику обработки данных от логики хранения, как сделано в STL
Комментариев нет:
Отправить комментарий