假設我有兩個文件: file1.c-包含名爲「array [10]」的大小爲10的int數組的全局定義。 file2.c-包含一個名爲「extern int * array」的int指針,在這裏我試圖將這個指針鏈接到數組。使用extern鏈接數組與指針
但是,當我檢查file1.c中的數組地址和file2.c中的指針值時,它們都是不同的。爲什麼會發生?
假設我有兩個文件: file1.c-包含名爲「array [10]」的大小爲10的int數組的全局定義。 file2.c-包含一個名爲「extern int * array」的int指針,在這裏我試圖將這個指針鏈接到數組。使用extern鏈接數組與指針
但是,當我檢查file1.c中的數組地址和file2.c中的指針值時,它們都是不同的。爲什麼會發生?
那是不行的,在file2.c
,你需要
extern int array[];
因爲數組和指針是不一樣的東西。這兩個聲明都必須具有兼容的類型,並且int*
與int[N]
不兼容。
沒有指定實際發生的情況,該程序與extern int *array;
不一致,但可能該數組的第一個sizeof(int*)
字節被解釋爲地址。
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],在測試函數中數組就是地址。
在'main'中,你不是打印地址,而是指向指針的值(在'test'中,指向傳遞給'printf'時數組轉換到的第一個元素的指針的值)。如果你在兩個地方都打印'&address',你會得到相同的輸出。好例證。 –
但是實際上在內存中發生了什麼?內存是否分配給數組(40字節)和指針(32位上的4個字節)? –
未定義的行爲(實際上是格式不正確的程序)。但是可能的話,teh數組的前四個(或八個)字節被解釋爲一個地址。 –
ok,但鏈接器將指針鏈接到數組,並且不報告編譯時錯誤。它實際上鍊接的是什麼? – Azazle