Я обнаружил, что это была ловушка, созданная нашим компилятором C!
(Так это стандарт CPL? C99 или что-то еще?)
Я написал следующий код в Visual Studio 2010 на платформе x86.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a[3] = { 0xa, 0xb, 0xc }; // Declare an array which include 3 items.
int len = sizeof(a) / sizeof(a[0]); // And the variable len refer to the code like @Neil Chowdhury o_O
int * pa0 = a; // Then i declared a pointer point to the first element to the source array a.
int len2 = sizeof(a) / sizeof(pa0[0]); // Len2 refer to the same action like previous statement.
int len3 = sizeof(a) / sizeof(pa0); // Len3 refer to a's size(one int's size)divide may be a int pointer's size.
int len4 = sizeof(pa0); // Len4 is the size of int pointer pa0.
int len5 = sizeof(a); // And len5 is the size of pa0, the same theory as previous stmt represented.
int len6 = sizeof(a[0]); // Len6 equal to sizeof(int)
int len7 = sizeof(pa0[0]); // Len7 equal to sizeof(int) too.
return 0;
}
Затем я собрал их и показал код разборки. Результаты лайков:
int a[3] = { 0xa, 0xb, 0xc };
00D13108 mov dword ptr [ebp-14h],0Ah
00D1310F mov dword ptr [ebp-10h],0Bh
00D13116 mov dword ptr [ebp-0Ch],0Ch
int len = sizeof(a) / sizeof(a[0]);
00D1311D mov dword ptr [ebp-20h],3 // caution!
int * pa0 = a;
00D13124 lea eax,[ebp-14h]
00D13127 mov dword ptr [ebp-2Ch],eax
int len2 = sizeof(a) / sizeof(pa0[0]);
00D1312A mov dword ptr [ebp-38h],3 // caution!
int len3 = sizeof(a) / sizeof(pa0);
00D13131 mov dword ptr [ebp-44h],3 // caution!
int len4 = sizeof(pa0);
00D13138 mov dword ptr [ebp-50h],4
int len5 = sizeof(a);
00D1313F mov dword ptr [ebp-5Ch],0Ch
int len6 = sizeof(a[0]);
00D13146 mov dword ptr [ebp-68h],4
int len7 = sizeof(pa0[0]);
00D1314D mov dword ptr [ebp-74h],4
return 0;
00D13154 xor eax,eax
Итак, что? посмотрите на эти "осторожные" отмеченные линии!
Как наш c-компилятор относился к нашему C-коду?
Когда приходит указатель, особенно когда мы написали предложение вроде
что-то = sizeof (один элемент массива) / sizeof (первый элемент этого массива)
Компилятор разбирает наш синтаксис как номер массива!
Это еще не закончено.
Я тоже протестировал "динамический массив". Массив, который выделяет malloc и т. Д.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int * a = NULL;
int len = 0;
a = (int *) calloc(7, sizeof(int));
len = sizeof(a) / sizeof(a[0]);
return 0;
}
Сборка .. Разборка ...
int * a = NULL;
013830FE mov dword ptr [a],0
int len = 0;
01383105 mov dword ptr [len],0
a = (int *) calloc(7, sizeof(int));
0138310C mov esi,esp
0138310E push 4
01383110 push 7
01383112 call dword ptr [__imp__calloc (13882CCh)]
01383118 add esp,8
0138311B cmp esi,esp
0138311D call @ILT+300(__RTC_CheckEsp) (1381131h)
01383122 mov dword ptr [a],eax
len = sizeof(a) / sizeof(a[0]);
01383125 mov dword ptr [len],1 // Hey!
return 0;
0138312C xor eax,eax
}
Вы это видите? компилятор пропустил наш синтаксис в это время.
Итак, вывод таков:
Когда вы пишете предложение, особенно, как:
что-то = sizeof (один элемент массива) / sizeof (первый элемент этого массива)
Компилятор поймет и проанализирует наш код, и что-то подпишет емкость массива. Только если исходный массив является фиксированным массивом или массив уже объявил размер ранее. (В настоящее время размер константы может храниться в таблице переменных компилятора.)
Это в основном как @rmn сказал.
Вот что я нашел. Может быть бесполезным.