2012-02-07 3 views
1

Там я что-то я не получаю, если есть следующие:Массивы и функции в языке Си

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?

+1

Если ваш вопрос о С, то почему вы используете тег '' C++? –

+2

И 'sizeof (score)' не будет 0. Это будет размер указателя. Об этом просили много лет. –

+0

@LightnessRacesinOrbit, потому что они очень похожи – Itzik984

ответ

6

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

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

+0

так почему я получаю 0? SizeOf (баллов) = SizeOf (аннулируются) = 4? и деление 0? – Itzik984

+2

@ Itzik984: Да, точно. На вашей платформе 'sizeof (double *)' is '4' и' sizeof (double) 'is' 8', поэтому 'sizeof (score)/sizeof (double)' is '4/8', что равно' 0 '. – ruakh

3

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

double average (double scores[]); 

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

double average (double *scores); 

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

0

scores является двойной * Const, следовательно, sizeof(scores) будет размер, необходимый для хранения указателя

1

Две вещи, чтобы помнить о массивах в C:

  1. исключением случаев, когда это операнд sizeof или унарный оператор &, или является строковым литералом, используемым для инициализации другого массива в объявлении, выражение типа «N-элементный массив из T» будет заменено на выражение («распад на») выражением типа «указатель на« 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. 
Смежные вопросы