宣告指定了乙個名字所關聯的型別,定義則更進一步指定了名字所對應的實體,
所謂的實體就是適當數量的儲存,乙個定義首先肯定是乙個宣告。
換句話說:能否根據**在記憶體中開闢出空間,是宣告與定義最大的區別,
在很多情況下不能簡單的根據宣告就能在記憶體中給變數(或者其他識別符號)開闢出空間。
任何描述了初始值的宣告都是乙個定義。
下面我們通過《c++程式語言(特別版)》上的習題來具體的分析宣告與定義
的區別:
首先給定一些宣告和定義:
char ch;
string s;
int count = 1;
const double pi = 3.1415;
extern int error_number;
const char *name = "njal";
const char *season = ;
struct date
; int day(date *p)
double sqrt(double);
templatet abs(t a)
typedef complexpoint;
struct user;
enum beer ;
namespace ns
那麼問題來了,這裡面哪些是宣告哪些是定義呢,該到了運用我們上面規則的時候了,
看編譯器是否能準備的開闢出空間。
這樣一來
char ch;
string s;
int count = 1;
比如這三行**,變數ch編譯器可以在記憶體中為其分配乙個位元組(char型變數佔一位元組),
s則是乙個位址,在記憶體中也有分配,count則是乙個整型變數,佔據記憶體的四個位元組。
同理我們也可以得到
const double pi = 3.1415;
const char *name = "njal";
const char *season = ;
struct date
; typedef complexpoint;
enum beer ;
這些都是定義。
還有兩個函式定義和名詞空間的定義可能不太號理解:
int day(date *p)
templatet abs(t a)
namespace ns
day函式和abs函式都是定義了函式實體的,所以這兩個指定函式的**也是定義。
對於名詞空間,我們可以理解為給一段程式蓋了一間屋子,在屋子裡打籃球跟在
戶外打籃球都是打籃球,屋子裡的漂移投籃跟屋子外的漂移投籃是乙個動作。
這樣就剩下非定義的宣告了:
extern int error_number;
double sqrt(double);
struct user;
這三行**所引用實體必須在其他地方定義,函式sqrt的**體必須通過另外的某個宣告描述,int變數error_number的儲存必須由某個另外的error_number的宣告去分配,
必須有另外的某個對型別user的宣告來定義出這個型別是什麼樣子。
下面我們來改寫那些不是定義的宣告,並將定義轉換為宣告。
對於extern int error_number是宣告了乙個引用外部的變數,其定義在另外的地方,
我們只要把extern去掉,變為本地宣告的變數即可。
沒有函式實體的函式宣告,我們新增上函式實體就是定義。
乙個class、struct、union或者enum如果帶有其所有成員的宣告,那麼它就是乙個
定義。無法寫出乙個不是定義的名字空間宣告。
按照上面的規則我們就可以實現將定義轉換為宣告如下:
將宣告轉化為定義如下:
到此我們就完成了例子,同學們定義與宣告的區別你們理解了嗎?
C 定義與宣告 區別
c primer 第四版2.3.5節中這麼說到 變數定義 用於為變數分配儲存空間,還可為變數指定初始值。程式中,變數有且僅有乙個定義。變數宣告 用於向程式表明變數的型別和名字。定義也是宣告 當定義變數時我們宣告了它的型別和名字。extern關鍵字 通過使用extern關鍵字宣告變數名而不定義它。1....
C 宣告與定義的區別
一,宣告與定義的區別 宣告是將乙個名稱引入程式。定義提供了乙個實體在程式中的唯一描述,涉及到記憶體空間的分配以及初始值的設定。宣告和定義有時是同時存在的。1,定義也是宣告,extern宣告不是定義,即不分配儲存空間。int a 10 定義就是宣告 extern int b 宣告,不是定義 注意 如果...
C中定義與宣告有什麼區別
判斷如下兩段 a和b哪乙個是定義,哪乙個是宣告 a int i b extern int i 所謂的定義就是 編譯器 建立乙個物件,為這個物件分配一塊記憶體並給它取上乙個名字,這個名字就是我們經常所說的變數名或物件名。變數名與記憶體空間繫結在一起,雙方都無法被改變。並且在乙個命名域內只能被定義一次。...