聲明變量&定義變量


        從編譯原理上來說,聲明是僅僅告訴編譯器,有個某類型的變量會被使用,但是編譯器並不會為它分配任何內存。而定義就是分配了內存。這對於以關鍵字extern進行聲明是一定成立的,而對聲明格式“int a;”來說,則需要取決於編譯器的具體取舍。

 

對於下面的兩句代碼:

void func()
{
    int a;           // 《C++ Prime》認為此是定義變量,然而我們此處認為這是聲明
    int b=1;        // 定義整型變量b
    a=0;
}

對於第一行代碼,編譯器不會做任何事,它不會為它在棧中分配一點東西,直到第三句,a=0;時,編譯器才會將其壓入棧中。而對於int b=0;這一句,編譯器就會生成一條指令,為它賦值。如果反匯編,看到的代碼可能是這樣的:

push 1;
push 0;

當然,並不一定編譯器就會樣做,也有可能在聲明int a時,編譯器就會把一個廢值入棧,到第三條再為其賦值,這要看編譯器的具體取舍,所以,聲明不一定不是定義,而定義一定是定義

但是,下面的聲明,一定僅僅是聲明:

extern int a;

這表時,有一個int變量a,它一定是在另外其他地方定義的,所以編譯器此時一定不會做什么分配內存的事,因為它就是聲明,僅僅表明下面的代碼引用了一個符號,而這個符號是int類型的a而已。

 

【舉例分析】

#include <iostream>
#include <cstdio> 

using namespace std;

void testVarible1()
{
	int a = 10;
	int b;				// 《C++ prime》中認為此是定義變量
	int c = 10;
	printf("a address: %#x\n", &a);
	printf("a address: %#x\n", &b);
	printf("c address: %#x\n", &c);
}

void testVarible2()
{
	int a = 10;
	int b = 10;
	int c = 10;
	printf("a address: %#x\n", &a);
	printf("a address: %#x\n", &b);
	printf("c address: %#x\n", &c);
}

int main()
{
	testVarible1();
	testVarible2();
	return 0;
}

輸出結果:

結論:由圖可知,在我的編譯器中,未賦初始值的變量b也有分配棧地址。

 

傳送門:《C++ Prime》中對於變量聲明和變量定義的理解

 

2018-3-24更新

  • 我們不再認為語句“int a;”為聲明變量,而是定義變量,只是沒有指定初始值。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM