Проблема с длиной массива

Я читал документ о размещении csc, где прочитал вопрос, связанный с оператором sizeof() массива языка c. Ответ был чем-то другим, чем я ожидал.

int DIMension(int array[]) {
   return sizeof(array )/ sizeof(int);
}

main() {
   int arr[10];
   printf(“Array dimension is %d”, DIMension(arr));
}

Эта программа на языке c выводит 1 в качестве ответа. Почему это происходит?


person Sourabh    schedule 09.09.2011    source источник
comment
Я думаю, что это должно быть return sizeof(array)/sizeof(int); Оператор, как написано выше, делит адрес, содержащийся в массиве, на sizeof (int).   -  person fvu    schedule 09.09.2011
comment
Этот вопрос задавался так много раз здесь, на SO   -  person Amit Singh Tomar    schedule 09.09.2011
comment
@fvu, в функции DIMension() array - это просто указатель int, поэтому ваше предложение тоже не сработает.   -  person Kusalananda    schedule 09.09.2011
comment
Можете ли вы предоставить мне несколько ссылок на этот тип вопросов ?? я был в состоянии найти любой ??   -  person Sourabh    schedule 09.09.2011
comment
@KAK то, что я предлагаю, реконструирует то, что я считаю ошибкой OP (1 при условии, что целые числа и указатели имеют длину 32 бита) вместо некоторого указателя, разделенного на 4 (что было бы неправильно). Так что правильных, как в указании правильной длины массива, нет, но хотя бы правильных в его неправильности :-)   -  person fvu    schedule 09.09.2011


Ответы (6)


Потому что int array[] - это просто указатель, и его размер такой же, как у int. Я думаю, вы ожидали, что размер arr каким-то образом будет передан в функцию, но это так не работает. Размер arr можно определить только в той же области видимости, где он был объявлен, потому что sizeof фактически работает во время компиляции.

person Andrey    schedule 09.09.2011
comment
но размер int на языке c равен 4, но он возвращает 1. Почему так?? - person Sourabh; 09.09.2011
comment
@sourabh you sizeof(array) [= размер указателя, который равен 4 в 32-битной среде] / sizeof(int) [который также равен 4] дает 4 / 4 = 1. Как говорит Андрей, нет способа делегировать расчет размера массива так, как вы пытались. - person fvu; 09.09.2011

Массив передается как указатель. Функция не может узнать, сколько места было выделено для массива.

person Tom Zych    schedule 09.09.2011

Все массивы распадаются на указатели, когда они передаются, поэтому выражение принимает вид: sizeof(void*)/sizeof(int), что соответствует 1 на 32-битных машинах с 32-битными int и 2 на 64-битных машинах с 32-битными int.

person Necrolis    schedule 09.09.2011

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

person Emil Romanus    schedule 09.09.2011

Массив в C — очень хрупкий тип. Есть много ситуаций, в которых массив распадается на указатель на первый элемент, и передача массива в качестве аргумента функции является такой ситуацией. Вот:

int main()
{
  char data[10];        // sizeof(data) == 10
  return call_me(data); // data is equivalent to &data[0] here!
}

int call_me(char x[])
// int call_me(char * x)   // same thing!
{
  // here sizeof(x) == sizeof(char *)
  // ...
}

Массивы характерны для C в том смысле, что они не могут быть переданы в качестве аргументов функции или возвращены из функций, поэтому вы часто будете видеть указатели, когда ожидаете массивы. Вызывающий объект (вы!) несет ответственность за предоставление достаточной информации для правильной интерпретации указателя как массива.

Обратите внимание, что распространенная идиома C создает «массив» полностью динамически, без упоминания типа массива: char * p = malloc(10); Здесь p никогда не бывает ничем иным, как указателем, и вы должны помнить, что можете обращаться с ним как с массивом.

(Ситуация немного лучше в C++, где вы можете передавать фактические массивы по ссылке.)

person Kerrek SB    schedule 09.09.2011

См. Синтаксис определения функции можно записать следующим образом.

 int DIMension(int array[]) {
 return sizeof(array )/ sizeof(int);
 }


 int DIMension(int *array) 
 {
 return sizeof(array )/ sizeof(int);
 }

int DIMension(int array[10])
{
return sizeof(array )/ sizeof(int);
}

Все эти три утверждения имеют одинаковое значение, и общим для всех трех является массив аргументов, который представляет собой не что иное, как указатель на массив, который всегда будет состоять из 4 байтов.

person Amit Singh Tomar    schedule 09.09.2011
comment
Потому что в используемой вами реализации sizeof(int) == sizeof(pointer). - person Tom Zych; 09.09.2011
comment
посмотрите, размер указателя 4 байта и int тоже 4 байта, так что разделите их, получится один. как sizeof(array)=4 , sizeof(int)=4 и 4/4 = 1 - person Amit Singh Tomar; 09.09.2011
comment
который всегда будет 4 байта. Не обязательно, это может быть любое количество байтов. - person James Greenhalgh; 09.09.2011