2012-11-25 15 views
2

Supposons que j'ai deux fichiers: file1.c- contient la définition globale d'un tableau int de taille 10 nommé "tableau [10]". file2.c- contient un pointeur int nommé "extern int * array", ici j'essaye de lier ce pointeur au tableau. Mais quand je vérifie l'adresse de tableau dans file1.c et la valeur de pointeur dans file2.c, ils sont tous les deux différents. Pourquoi cela se passe-t-il?en utilisant extern pour lier un tableau avec un pointeur

Répondre

5

qui ne fonctionne pas, en file2.c, vous avez besoin

extern int array[]; 

puisque les tableaux et les pointeurs ne sont pas la même chose. Les deux déclarations doivent avoir les types compatibles, et int* n'est pas compatible avec int[N]. Ce qui se passe réellement n'est pas spécifié, le programme est mal formé avec extern int *array;, mais probablement, les premiers sizeof(int*) octets du tableau sont interprétés comme une adresse.

+0

Mais que se passe-t-il réellement dans la mémoire? La mémoire est-elle allouée à la fois au tableau (40 octets) et au pointeur (4 octets sur 32 bits)? –

+0

Comportement non défini (programme mal formé, en fait). Mais probablement, les quatre premiers (ou huit) octets du tableau sont interprétés comme une adresse. –

+0

ok, mais l'éditeur de liens lie le pointeur à un tableau et ne signale pas une erreur de compilation. Pour ce qu'il relie réellement? – Azazle

1

extern1.c

#include <stdio.h> 

extern int *array; 
int test(); 

int main(int argc, char *argv[]) 
{ 
    printf ("in main: array address = %x\n", array); 
    test(); 
    return 0; 
} 

extern2.c

int array[10] = {1, 2, 3}; 

int test() 
{ 
    printf ("in test: array address = %x\n", array); 
    return 0; 
} 

La sortie:

in main: array address = 1 
in test: array address = 804a040 

Et le code assembler:

08048404 <main>: 
8048404:  55      push %ebp 
8048405:  89 e5     mov %esp,%ebp 
8048407:  83 e4 f0    and $0xfffffff0,%esp 
804840a:  83 ec 10    sub $0x10,%esp 
804840d:  8b 15 40 a0 04 08  mov 0x804a040,%edx <--------- this (1) 
8048413:  b8 20 85 04 08   mov $0x8048520,%eax 
8048418:  89 54 24 04    mov %edx,0x4(%esp) 
804841c:  89 04 24    mov %eax,(%esp) 
804841f:  e8 dc fe ff ff   call 8048300 <[email protected]> 
8048424:  e8 07 00 00 00   call 8048430 <test> 
8048429:  b8 00 00 00 00   mov $0x0,%eax 
804842e:  c9      leave 
804842f:  c3      ret  

08048430 <test>: 
8048430:  55      push %ebp 
8048431:  89 e5     mov %esp,%ebp 
8048433:  83 ec 18    sub $0x18,%esp 
8048436:  c7 44 24 04 40 a0 04 movl $0x804a040,0x4(%esp) <------- this (2) 
804843d:  08 
804843e:  c7 04 24 3d 85 04 08 movl $0x804853d,(%esp) 
8048445:  e8 b6 fe ff ff   call 8048300 <[email protected]> 
804844a:  b8 00 00 00 00   mov $0x0,%eax 
804844f:  c9      leave 
8048450:  c3      ret 

Faites attention au < ------- dans le code d'assemblage. Vous pouvez voir dans la fonction principale que le tableau est array [0] et dans la fonction test le tableau est l'adresse.

+0

Dans 'main' vous n'imprimez pas l'adresse, mais la valeur du pointeur (et dans' test', la valeur du pointeur vers le premier élément dans lequel le tableau est converti lorsqu'il est passé à 'printf'). Si vous imprimez '& adresse' dans les deux, vous obtiendrez la même sortie. Bonne illustration –

Questions connexes