C語(yǔ)言詳細(xì)分析講解多文件的程序設(shè)計(jì)
一、多文件與編譯器鏈接
如下圖所示,.o 為目標(biāo)文件,鏈接器將不同的目標(biāo)文件裝配組合在一起形成一個(gè)可執(zhí)行文件。
二、多文件之間的相互訪問(wèn)
每個(gè)文件可以定義功能接口(可被其它文件訪問(wèn)的函數(shù)或數(shù)據(jù))
- 源文件:代碼實(shí)現(xiàn)文件,后綴為.c
- 頭文件:源文件的接口定義文件,后綴為.h
當(dāng)需要使用其它文件提供的功能時(shí),包含對(duì)應(yīng)的頭文件
語(yǔ)法:
#include <hearer.h>
#include "header.h"
三、關(guān)于#include
#include 用于聲明使用其它文件的功能(頭文件可看作工具包)
#include <...>
在編譯系統(tǒng)文件中查找頭文件
#include "..."
先查找當(dāng)前工程文件夾,再查找編譯統(tǒng)文件夾
四、頭文件使用的一些原則
- 頭文件中只做函數(shù)聲明和變量聲明(不做具體定義)
- 頭文件中可定義數(shù)據(jù)類(lèi)型(typedef, struct, union, enum)
- 根據(jù)具體實(shí)現(xiàn),一個(gè)頭文件可對(duì)應(yīng)多個(gè)源文件(多數(shù)情況一對(duì)一)
- 不要使用#include語(yǔ)句包含源文件
五、再論全局變量
普通全局變量
- 源文件中定義的全局變量可在所有其它源文件中使用
- 可使用 extern 關(guān)鍵字在頭文件中進(jìn)行聲明,并在其它文件使用
靜態(tài)全局變量
- static 修飾的全局變量只能在當(dāng)前源文件中使用
- 無(wú)法通過(guò) extern 關(guān)鍵字聲明,在其它文件使用
六、注意事項(xiàng)
函數(shù)聲明語(yǔ)句默認(rèn)自帶 extern 關(guān)鍵字修飾
類(lèi)型定義必須在頭文件中,僅類(lèi)型聲明無(wú)法創(chuàng)建變量
靜態(tài)全局變量
- 生命期為程序運(yùn)行期
- 作用域僅在定義的文件中
- 無(wú)法直接在其它文件中使用
static 關(guān)鍵字可使函數(shù)具備文件作用域(靜態(tài)函數(shù))
靜態(tài)函數(shù)無(wú)法在其它文件中被調(diào)用
函數(shù)設(shè)計(jì)時(shí)需要考慮是否在其它文件中使用
七、實(shí)驗(yàn)程序
以CodeBlcoks為例,先建好 main.c 文件之后,點(diǎn)擊File,New,再點(diǎn)擊File,選擇 Empty file,分別建一個(gè) .h 和 .c 文件,完成多文件創(chuàng)建。
opm.h 代碼:
struct Test { int a; int b; }; extern int g_var; // 聲明全局變量時(shí),不需要給出初始值 extern int f_var; int add(int a, int b); int mul(int, int); // 進(jìn)行函數(shù)聲明的時(shí)候,可以省略參數(shù)名 extern void test();
opm.c 代碼:
#include <stdio.h> int g_var = 1; static int f_var = 2; // 只能在當(dāng)前文件中使用 ==> 靜態(tài)全局變量 static void func() // 靜態(tài)函數(shù)只能在當(dāng)前文件中被調(diào)用 { printf("void func() : f_var = %d\n", f_var); } void test() // 當(dāng)前文件中定義的所有函數(shù)都可以調(diào)用 func() 函數(shù) { func(); } int add(int a, int b) { return a + b; } int mul(int a, int b) { return a * b; }
main.c 代碼:
#include <stdio.h> #include <string.h> #include "opm.h" int main() { struct Test t = {1, 2}; printf("a + b = %d\n", add(t.a, t.b)); printf("a * b = %d\n", mul(t.a, t.b)); printf("g_var = %d\n", g_var); // printf("f_var = %d\n", f_var); // 無(wú)法直接使用其他文件中定義的靜態(tài)全局變量 test(); return 0; }
下面為輸出結(jié)果:
通過(guò)這個(gè)多文件程序,說(shuō)明一個(gè)問(wèn)題:
static 修飾的全局變量和函數(shù)只能在當(dāng)前源文件中使用,所以 func() 函數(shù)不能再 main 函數(shù)中調(diào)用,而 test() 函數(shù)可以在 main 函數(shù)中被調(diào)用。
八、小結(jié)
- 實(shí)際工程開(kāi)發(fā)中,多文件程序設(shè)計(jì)是常態(tài)
- 源文件實(shí)現(xiàn)具體功能,頭文件聲明接口
- #include 用于聲明需要使用其它文件中定義的功能
- extern關(guān)鍵字用于函數(shù)和全局變量的聲明
- static 關(guān)鍵字修飾的全局變量不能在其它文件中使用
到此這篇關(guān)于C語(yǔ)言詳細(xì)分析講解多文件的程序設(shè)計(jì)的文章就介紹到這了,更多相關(guān)C語(yǔ)言 多文件程序設(shè)計(jì)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Qt數(shù)據(jù)庫(kù)應(yīng)用之實(shí)現(xiàn)通用數(shù)據(jù)庫(kù)請(qǐng)求
這篇文章主要為大家介紹了Qt中是如何實(shí)現(xiàn)通用數(shù)據(jù)庫(kù)請(qǐng)求的,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Qt有一定幫助,感興趣的小伙伴可以了解一下2022-03-03QT出現(xiàn)沒(méi)有MySQL驅(qū)動(dòng)手動(dòng)編譯詳細(xì)步驟
這篇文章主要給大家介紹了關(guān)于QT出現(xiàn)沒(méi)有MySQL驅(qū)動(dòng)手動(dòng)編譯詳細(xì)步驟的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用QT具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2023-04-04Qt?QDateTime計(jì)算時(shí)間差的實(shí)現(xiàn)示例
本文主要介紹了Qt?QDateTime計(jì)算時(shí)間差的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04C++中引用、內(nèi)聯(lián)函數(shù)、auto關(guān)鍵字和范圍for循環(huán)詳解
本文主要梳理了C++當(dāng)中一些瑣碎的知識(shí)點(diǎn),包括有命名空間,缺省參數(shù),引用,auto關(guān)鍵字和內(nèi)聯(lián)函數(shù),文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2023-02-02