[C]關於extern與struct


問題

我曾經很困惑,就是在兩個編譯單元當中,如何把一個單元中聲明的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'


免責聲明!

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



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