Аргументы в прототипе функции - PullRequest
4 голосов
/ 16 июля 2010

Мой вопрос: когда я пишу прототип функции на C, как это:

void foo(int *vector);

Это то же самое, что и делать:

void foo(int vector[MAX_LENGTH]);

В функцию передается всегдав качестве указателя?Код это то же самое?Заранее спасибо.

Ответы [ 4 ]

8 голосов
/ 16 июля 2010

Это тонко.Массивы в C не являются указателями, но C не позволяет передавать массивы в качестве параметров функции.Поэтому, когда у вас есть void foo(int vector[MAX_LENGTH]);, по сути, все, что вы делаете, это говорите другим программистам (и вашему будущему себе), что эта функция ожидает, что массив MAX_LENGTH будет передан ей.Компилятор вам не поможет.Он бесшумно приведёт ваш массив к указателю.

Это объясняет это довольно хорошо.

6 голосов
/ 16 июля 2010

Да, тип массива неявно преобразуется в тип указателя при передаче в функцию.

Так

void foo(int *a) и void foo(int a[]) идентичны.

Вы можете легко проверить это с помощью оператора sizeof() внутри определения функции

Например

void foo(int a[])
{
   std::cout<<sizeof(a); //prints sizeof(int*)
}

int main()
{

   int a[]={1,2,3,4};
   foo(a);
}

ДОПОЛНИТЕЛЬНО (Размер печати массива внутри функции)

[C++ Only]

 template<typename T,size_t n>
 void size_of_array(T (&a)[n]) //Array passed by reference. Template argument deduction 
 {
    std::cout<<sizeof(a); //prints sizeof(n*sizeof(int))
 }

 int main()
 {
      int a[]={1,2,3,4,5};
      size_of_array(a);
 }
2 голосов
/ 16 июля 2010

Это один из грубых краев языка (ов) Си.Два объявления, которые выглядят одинаково (но для имен), одно в прототипе, а другое в качестве переменной стека, приводит к объявлению двух различных типов переменных.

void foo(int A[10]) {
   int B[10];    
}

Внутри области действия foo, A - это указатель на int , а B - это массив из десяти элементов типа int.Как уже упоминалось, даже их размеры, вычисленные с помощью sizeof, различаются.

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

C99 усложняетэто еще более важно, введя новое ключевое слово static; -)

void foo(int A[static 10]) {
   int B[10];    
}

, это не меняет правила того, как A и B видны изнутри, но предоставляет информациюк вызывающей стороне, как ожидаются элементы массива.На данный момент gcc принимает этот новый синтаксис и просто игнорирует эту информацию.

1 голос
/ 16 июля 2010

мало что еще может пройти!Однако [] ограничение позволяет компилятору делать больше проверок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...