C語言定義和宣告區別

2021-06-18 12:31:29 字數 2603 閱讀 7324

1. 變數的定義和宣告

c語言定義和宣告分為變數的定義和宣告和函式的定義和宣告。由於,函式是具有全域性外部特性,並且函式的定義和宣告區別是很明顯的。其宣告需要返回值型別,函式名和引數列表。而函式的定義需要函式體。所以,很容易區別函式的宣告和定義。對於變數的宣告和定義,就不是那麼明顯。通常變數定義和宣告的區別是有沒有為變數分配記憶體。如果為變數分配記憶體就是定義,否則就是宣告。變數宣告可以出現多次,但定義只能出現一次。

2. 強符號和弱符號

強符號:函式和初始化的全域性變數稱為強符號。

弱符號:  未初始化的全域性變數稱為弱符號。

在程式中,強符號只能出現1次,弱符號會出現多次。如果存在乙個強符號和多個弱符號,gcc會選擇強符號。如果存在多個弱符號,會選擇其中乙個弱符號作為定義,並分配記憶體。

3. 例項

例項1:多個強符號

三個檔案test11.h, test11.c和test22.c,具體如下:

test11.h:

#ifndef _test1_h

#define _test1_h

#include int i=1; //此處i是定義,是強符號

void printmsg();

#endif

test11.c

#include "test11.h"

void printmsg()

test22.c

#include "test11.h"

int main()

編譯結果:

test11.o:(.data+0x0): multiple definition of `i'

test22.o:(.data+0x0): first defined here

由於出現了多個強符號,所以鏈結時i重定義了。

例項2:多個弱符號和1個強符號

test11.h

#ifndef _test1_h

#define _test1_h

#include int i;

int i;

void printmsg();

#endif

此處int i,準確來說是定義性宣告,既是定義也是宣告,但沒有初始化,稱為弱符號。

test11.c

#include "test11.h"

void printmsg()

test22.c

#include "test11.h"

int i=10;

int main()

在test33.c對i進行了定義,為強符號。

執行結果:

i=10

當存在多個弱符號和1個強符號時,gcc會選擇強符號,能夠正常的編譯和執行。

例項3:多個弱符號

test11.h

#ifndef _test1_h

#define _test1_h

#include int i;

int i;

void printmsg();

#endif

此處int i,準確來說是定義性宣告,既是定義也是宣告,但沒有初始化,稱為弱符號。

test11.c

#include "test11.h"

void printmsg()

test22.c

#include "test11.h"

int main()

去掉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語言定義和宣告區別

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 對於結構體型別如果只有宣...