2012-11-25 31 views
2

假設我有兩個文件: file1.c-包含名爲「array [10]」的大小爲10的int數組的全局定義。 file2.c-包含一個名爲「extern int * array」的int指針,在這裏我試圖將這個指針鏈接到數組。使用extern鏈接數組與指針

但是,當我檢查file1.c中的數組地址和file2.c中的指針值時,它們都是不同的。爲什麼會發生?

回答

5

那是不行的,在file2.c,你需要

extern int array[]; 

因爲數組和指針是不一樣的東西。這兩個聲明都必須具有兼容的類型,並且int*int[N]不兼容。

沒有指定實際發生的情況,該程序與extern int *array;不一致,但可能該數組的第一個sizeof(int*)字節被解釋爲地址。

+0

但是實際上在內存中發生了什麼?內存是否分配給數組(40字節)和指針(32位上的4個字節)? –

+0

未定義的行爲(實際上是格式不正確的程序)。但是可能的話,teh數組的前四個(或八個)字節被解釋爲一個地址。 –

+0

ok,但鏈接器將指針鏈接到數組,並且不報告編譯時錯誤。它實際上鍊接的是什麼? – 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; 
} 

輸出:

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

而彙編代碼:

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 

請注意彙編代碼中的< -------。你可以在main函數中看到數組是array [0],在測試函數中數組就是地址。

+0

在'main'中,你不是打印地址,而是指向指針的值(在'test'中,指向傳遞給'printf'時數組轉換到的第一個元素的指針的值)。如果你在兩個地方都打印'&address',你會得到相同的輸出。好例證。 –