Проблем с дължината на масива

Четох документ за поставяне на 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 вие 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-битови ints и 2 на 64-битови машини с 32-битови ints.

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