c語言定義和宣告區別
1. 變數的定義和宣告
c語言定義和宣告分為變數的定義和宣告和函式的定義和宣告。由於,函式是具有全域性外部特性,並且函式的定義和宣告區別是很明顯的。其宣告需要返回值型別,函式名和引數列表。而函式的定義需要函式體。所以,很容易區別函式的宣告和定義。對於變數的宣告和定義,就不是那麼明顯。通常變數定義和宣告的區別是有沒有為變數分配記憶體。如果為變數分配記憶體就是定義,否則就是宣告。變數宣告可以出現多次,但定義只能出現一次。
2. 強符號和弱符號
強符號:函式和初始化的全域性變數稱為強符號。
弱符號: 未初始化的全域性變數稱為弱符號。
在程式中,強符號只能出現1次,弱符號會出現多次。如果存在乙個強符號和多個弱符號,gcc會選擇強符號。如果存在多個弱符號,會選擇其中乙個弱符號作為定義,並分配記憶體。
3. 例項
例項1:多個強符號
三個檔案test11.h, test11.c和test22.c,具體如下:
test11.h:
[cpp]view plain
copy
#ifndef _test1_h
#define _test1_h
#include
inti=1;
//此處i是定義,是強符號
void
printmsg();
#endif
test11.c
[cpp]view plain
copy
#include "test11.h"
void
printmsg()
test22.c
[cpp]view plain
copy
#include "test11.h"
intmain()
編譯結果:
test11.o:(.data+0x0): multiple definition of `i'
test22.o:(.data+0x0): first defined here
由於出現了多個強符號,所以鏈結時i重定義了。
例項2:多個弱符號和1個強符號
test11.h
[cpp]view plain
copy
#ifndef _test1_h
#define _test1_h
#include
inti;
inti;
void
printmsg();
#endif
此處int i,準確來說是定義性宣告,既是定義也是宣告,但沒有初始化,稱為弱符號。
test11.c
[cpp]view plain
copy
#include "test11.h"
void
printmsg()
test22.c
[cpp]view plain
copy
#include "test11.h"
inti=10;
intmain()
在test33.c對i進行了定義,為強符號。
執行結果:
i=10
當存在多個弱符號和1個強符號時,gcc會選擇強符號,能夠正常的編譯和執行。
例項3:多個弱符號
test11.h
[cpp]view plain
copy
#ifndef _test1_h
#define _test1_h
#include
inti;
inti;
void
printmsg();
#endif
此處int i,準確來說是定義性宣告,既是定義也是宣告,但沒有初始化,稱為弱符號。
test11.c
[cpp]view plain
copy
#include "test11.h"
void
printmsg()
test22.c
[cpp]view plain
copy
#include "test11.h"
intmain()
去掉test22.c中的i定義,此時只有多個弱符號。
執行結果:
i=0;
當存在多個弱符號時,gcc會選擇其中乙個弱符號作為定義。由於i未初始化,所以儲存在.bss段上,關於變數儲存位置,將在以後文章作詳細介紹。.bss段變數用0進行填充。
注意: 當gcc編譯器看到 int i時,在鏈結的時候,搜尋源程式,如果定義變數i(有初始值),就把此處的i看成是宣告。如果別處沒有定義,就為此處的i分配空間,即當作定義。
所以: i的轉換過程為:定義性宣告((或稱為暫定義)->定義。
4. 結構體的定義和宣告
struct a;
稱為型別定義,和變數定義完全不同。即定義一種新的資料型別,類似int型別。如果gcc在編譯時檢查出多個結構體定義,就會報重定義錯誤。即某個程式出現了:
struct a{};
struct a{};
在鏈結時,如果多個檔案中存在結構體定義,則不會報錯,gcc在鏈結時只檢查符號,這裡的符號指的是變數和函式之類的符號,而不是型別符號。不會檢查語法。所以在多個檔案中出現結構體定義沒有問題。
struct a a1;
a1稱為結構體變數宣告,和普通變數類似。
總結:(1)變數定義和宣告的本質區別:是否分配記憶體。
(2)區域性變數不能多次宣告,即在同一**塊(即同一作用域)的區域性變數不可多次宣告。區域性變數不能出現 int i; int i;
(3)需要強調的是,不要在標頭檔案定義全域性變數,容易引起重定義。
C語言定義和宣告區別
1.變數的定義和宣告 c語言定義和宣告分為變數的定義和宣告和函式的定義和宣告。由於,函式是具有全域性外部特性,並且函式的定義和宣告區別是很明顯的。其宣告需要返回值型別,函式名和引數列表。而函式的定義需要函式體。所以,很容易區別函式的宣告和定義。對於變數的宣告和定義,就不是那麼明顯。通常變數定義和宣告...
定義和宣告的區別
之前學習c c 的時候,都沒去注意變數的定義和宣告的具體區別,也隨意將它們放在標頭檔案,今日看c primer,才發現原來變數的定義和宣告之間的區別竟然如此之大,而且區別它們兩個竟然如此重要。變數的定義用於為變數分配儲存空間,還可以為變數指定初始值。在乙個程式中,變數有且僅有乙個定義。宣告用於向程式...
定義和宣告的區別
2 變數定義和變數宣告的區別 3 物件定義和物件宣告的區別 關於宣告和定義有如下兩種特殊情況需要注意 1 宣告和定義如果變數型別不一致,將導致錯誤的解析。global.c float g f 10.0 main.c extern int g f intmain void 2 對於結構體型別如果只有宣...