爲什麼下面的代碼會被編譯? 何時'num'變量獲取其值?'extern'關鍵字會使下列代碼合法嗎?
#include <stdio.h>
extern int num;
void main()
{
printf("%d", num); //prints 3
}
int num = 3;
例子:Live Code
爲什麼下面的代碼會被編譯? 何時'num'變量獲取其值?'extern'關鍵字會使下列代碼合法嗎?
#include <stdio.h>
extern int num;
void main()
{
printf("%d", num); //prints 3
}
int num = 3;
例子:Live Code
在你的代碼,
extern int num;
被稱爲聲明。 OTOH,
int num = 3;
是具有顯式初始化的定義。此聲明設置的值。該值在編譯時決定,並在main()
開始執行之前設置。
也就是說,void main()
應該是int main(void)
,至少要符合標準。
OP在問什麼時候。答案是「就在'main'運行之前」。 –
是的,我知道聲明和定義之間的區別,但這裏的要點是'num'在調用main之後被聲明;實際上,如果你刪除了extern關鍵字,它將不會編譯! – Nemmy
這裏,它與函數原型相似。 'extern'使它可用,儘管它的價值(實現)是在後面定義的。編譯器確保它的值在'main'運行之前被設置,儘管它在源文件中被定義。 –
extern
與聲明一起使用。它告訴編譯器,這個東西將在其他地方定義。當你有多個使用相同變量或函數的文件時,這很有用。你可以在頭文件中放入一個extern
聲明,並在源文件中定義共享變量/函數。
如果您從代碼中刪除extern
您將定義兩次num
,這是不允許的。要擺脫extern
聲明,只需將您的int num = 3;
置於文件的頂部。
它的工作原理,因爲你已經聲明num
因此它可以在函數的代碼進行命名,因爲你在命名空間內,使得它在靜態初始化時間,這僅僅是main
是前初始化定義它執行。
在這個意義上,你的程序作爲當前寫入是從以下很難區別:
#include <stdio.h>
int num = 3;
void main()
{
printf("%d", num); //prints 3
}
「去哪兒」你初始化變量不是特別重要,只要假以時日,你出現之前嘗試使用它。
順便說一句,您必須使main
返回int
,而不是void
。
extern
標記後面定義的變量聲明。定義int num = 3;
部分是爲變量實際分配內存並設置其值(它也作爲聲明加倍)。 C/C++在使用之前聲明,如果你沒有這樣做extern int num;
那麼num
不會在你使用它的地方聲明。您當然也可以刪除extern
一行,並將num
的定義提高到main()
以上。
這裏有兩件事情發揮作用。在編譯期間,num
必須在使用之前在源文件中的某一點聲明。至於什麼時候它被賦值,這是在程序加載過程中發生的。在num
之類的文件範圍(在任何函數之外)的所有變量都分配了它們的內存,並且在調用main()
之前初始化了它們的值。如果它們在定義中沒有被賦予一個值,那麼它們可能包含任何東西,所以不要對未初始化變量的值做任何假設。你也不能對它們初始化的順序做任何假設,所以當初始化一個像這樣的變量時,不要引用其他文件範圍變量。
如果我刪除'extern',會有什麼問題? –
你有沒有使用'extern'在多個文件中使用變量?這工作原理相同,但在一個文件中。 – immibis
@SouravGhosh代碼不會編譯 – Nemmy