Lors de la conversion d’un tableau int en un court *, pourquoi l’affectation d’une valeur à un élément écrase-t-elle l’entier entier?

Je regarde la vidéo de Jerry Cain, Programming Paradigms Lecture 3, qui montre l’effet d’une assignation d’élément après la transposition entre un tableau int et un tableau court. L’argument est essentiellement que si vous deviez assigner un élément de tableau int arr[3] = 128 , alors transtyper temporairement le tableau int en un court * et assigner arr[6] = 2 , alors arr [3] deviendrait 128 + 512 = 640 car le 2 serait interprété comme étant à la 2 ^ 9ème position. Code pour démontrer:

 #include  int main() { printf("sizeof(int) is %lu\n", sizeof(int)); printf("sizeof(short) is %lu\n", sizeof(short)); int arr[5]; arr[3] = 128; ((short*)arr)[6] = 2; printf("arr[3] is equal to %d\n", arr[3]); //expect 640, get 2 instead return 0; } 

Quand j’exécute ce code, j’obtiens le résultat suivant:

 sizeof(int) is 4 sizeof(short) is 2 arr[3] is equal to 2 

Je m’attends à ce que arr [3] soit égal à 640, mais il est simplement égal à 2. Je suis certes un C noob – quelqu’un peut-il expliquer?

Big-endian vs little-endian, je pense.

Le code est insortingnsèquement spécifique à la plateforme (comportement officiel, presque certainement non défini). Je ne suis pas sûr que vous devriez l’apprendre, mais c’est, je suppose, un problème pour une autre fois.

Le 2 est assigné à deux des quatre octets de arr[3] . Si vous avez affecté à ((short *)arr)[7] place, vous pourriez voir le résultat attendu.

Sur quelle machine testez-vous (quel type de CPU)?


À bien y penser, même si une partie du problème est peut-être celle du big-endian ou du petit-endian, l’autre problème est celle du short ou du char . Voici un peu plus de code qui montre différentes voies vers la solution:

 #include  int main(void) { printf("sizeof(int) is %lu\n", sizeof(int)); printf("sizeof(short) is %lu\n", sizeof(short)); int arr[5]; arr[3] = 128; ((short*)arr)[6] = 2; printf("arr[3] is equal to %8d (0x%08X)\n", arr[3], arr[3]); arr[3] = 128; ((short*)arr)[7] = 2; printf("arr[3] is equal to %8d (0x%08X)\n", arr[3], arr[3]); for (int i = 12; i < 16; i++) { arr[3] = 128; ((char *)arr)[i] = 2; printf("arr[3] is equal to %8d (0x%08X) i = %d\n", arr[3], arr[3], i); } return 0; } 

La sortie de ce code révisé est:

 sizeof(int) is 4 sizeof(short) is 2 arr[3] is equal to 2 (0x00000002) arr[3] is equal to 131200 (0x00020080) arr[3] is equal to 2 (0x00000002) i = 12 arr[3] is equal to 640 (0x00000280) i = 13 arr[3] is equal to 131200 (0x00020080) i = 14 arr[3] is equal to 33554560 (0x02000080) i = 15 

Test sous MacOS X 10.7.2 avec GCC 4.2.1 XCode 4.2 (LLVM).