問題
我曾經很困惑,就是在兩個編譯單元當中,如何把一個單元中聲明的struct結構引入到另外一個單元中來,折騰了很久,后來發現這位大神的留言
不是這么用的…… 類型的定義和類型變量的定義不同, 類型定義只是描述一個類型, 是給編譯器看的, 不會產生可執行代碼。 變量定義是指在執行文件中真實得存在這么一塊內容。 因為每個.c里都要寫清楚類型定義很麻煩, 所以一般都把類型定義寫在.h里 ,而在.c里采用簡單的寫法,如struct A a; 這樣定義變量, 不需把整個類型的描述再寫一遍。 -------------------------------- 所以,struct類型定義放到 ser.h里面, ser.cpp 里加struct str st_r; CmfcDlg.cpp加上#include "ser.h" 然后直接使用extern struct str st_r; -------------------------------- 樓主要有研究精神…… 你先試下我上面說的…… |
我頓時發現自己是有多么的傻x.
說白了extern面向結構的語法,只針對對象的本身,而不包括結構,結構只是一個模板,是寫給編譯器看得。並不存在extern結構的說法,只能extern結構對象。
如果需要在兩個編譯單元內引入外部變量,那么你必須在兩個文件當中引入這個結構,才能使用。
最科學的方法就是把結構寫進一個.h文件,然后把它各自#include進每一個需要用到這個結構的文件當中。
示例,在a.c中聲明結構chicken,隨后聲明一個叫jason的chicken對象。把jason引入b.c
a.c
struct chicken { char name[20]; int age; }; struct chicken jason = { "jason", 2 };
b.c
#include <stdio.h> struct chicken { char name[20]; int age; }; extern struct chicken jason; int main(void) { printf("%s\n", jason.name);//輸出jason }
這個例子有一個不合理的地方,就是兩個文件都需要在各自上下文中聲明結構chicken,一旦結構chicken有所改動,就會相當麻煩,你需要修改所有包含了該結構的頁面。
所以這種情況下,通常會采取把結構聲明語句挪出來獨立作為一個頭文件,之后用到的地方各自引用該頭文件,下面是改動過的示例。
結構chicken被單獨至於這個chicken.h文件當中:
struct chicken { char name[20]; int age; };
a.c:
#include "chicken.h" struct chicken jason = { "jason Chao", 2 };
b.c:
#include <stdio.h> #include "chicken.h" //extern struct chicken jason; struct chicken jason; int main(void) { printf("%s\n", jason.name); }
結果是b.c會正常輸出jason.name.
題外話
1.其實extern關鍵字是c的標識符聲明中的[存儲類修飾符]的一員,[存儲類修飾符]包括extern、static、auto、register,在聲明變量、函數、結構化數據時,extern標識符是默認的,也就是說,上面的例子即使不手動指明extern關鍵字,編譯器也會默認把它當成extern關鍵字處理.
a.c
struct chicken { char name[20]; int age; }; struct chicken jason = { "jason", 2 };
b.c
#include <stdio.h> struct chicken { char name[20]; int age; }; struct chicken jason;//等價於extern struct chicken jason; int main(void) { printf("%s\n", jason.name);//輸出jason }
2.注意哦,變量只能初始化(賦予變量字面值)一次,就算外部變量也是一樣哦,不然編譯器會提示multiple definition of `xxx'