Массивы и функции на языке c - PullRequest
1 голос
/ 08 февраля 2012

Есть что-то, чего я не могу получить, если есть следующее:

double average (double scores[]){

 double sum = 0;
 int n;
 int nscores = sizeof(scores)/sizeof(double);
 for (n=0 ;n<nscores ;++n){
 sum+=scores [n];
 return sum/nscores;
}

и я отправляю эту функцию массиву так:

  double scores[3]={1,2,3};

почему sizeof (очки) будет 0?

Ответы [ 4 ]

6 голосов
/ 08 февраля 2012

sizeof(scores) внутри функции эквивалентно sizeof(double *): в этот момент компилятор не может сказать, насколько большим был массив.

Это не будет нулем, а потому что sizeof(scores) и sizeof(double) оба являются выражениями целочисленного типа, sizeof(scores)/sizeof(double) является целочисленным делением, поэтому, если sizeof(scores) < sizeof(double), то sizeof(scores)/sizeof(double) == 0.

3 голосов
/ 08 февраля 2012

Это потому, что массив как параметр функции рассматривается как указатель. Например,

double average (double scores[]);

... эквивалентно:

double average (double *scores);

и так sizeof(scores)/sizeof(double) равно sizeof(double *)/sizeof(double), и если эти типы имеют одинаковый размер, результат будет 1, но если размер double равен 8, а указатель равен 4, тогда результат будет 0.

1 голос
/ 08 февраля 2012

Две вещи, которые нужно помнить о массивах в C:

  1. За исключением случаев, когда это операнд оператора sizeof или унарный & или строковый литерал, используемый дляинициализировать другой массив в объявлении, выражение типа «массив N-элементов из T» будет заменено («decay to») выражением типа «указатель на T», значением которого является адрес первогоэлемент массива.

  2. В контексте объявления параметров функции T a[] и T a[N] идентичны T *a;IOW, a объявлен как указатель на T, а не как массив.Обратите внимание, что это верно только для объявлений параметров функции.

Когда вы вызываете average(scores) из своей основной функции, выражение scores будет заменено другим выражением типа double *, так что average получает указатель значение, а не массив.Таким образом, уловка sizeof для получения количества элементов не будет работать в функции average.Вам нужно будет передать количество элементов в scores как отдельный параметр, например, так:

double average(double *scores, size_t count)
{
   ...
}

и назвать его как

average(scores, sizeof scores / sizeof *scores); // or pass a constant 3, or
                                                 // something similar.
0 голосов
/ 08 февраля 2012

scores - это двойное * const, поэтому sizeof(scores) будет размером, необходимым для хранения указателя

...