C++編程入門系列之二十四(C++程序設(shè)計(jì)必知:多文件結(jié)構(gòu)和編譯預(yù)處理命令)分類標(biāo)簽: C++ 編程入門 -

我們提供的服務(wù)有:網(wǎng)站建設(shè)、做網(wǎng)站、微信公眾號(hào)開(kāi)發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、夏縣ssl等。為上千余家企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的夏縣網(wǎng)站制作公司
雞啄米上一講給大家講了常引用、常對(duì)象和對(duì)象的常成員,今天給大家講下編程入門知識(shí)--多文件結(jié)構(gòu)和編譯預(yù)處理命令。
一.C++程序的多文件結(jié)構(gòu)
之前雞啄米給大家看了很多比較完整的C++程序的例子,大家可能發(fā)現(xiàn)了,它們的結(jié)構(gòu)基本上可以分為三個(gè)部分:類的聲明、類的成員函數(shù)的實(shí)現(xiàn)和主函數(shù)。因?yàn)榇a比較少,所以可以把它們寫在一個(gè)文件中,但是我們實(shí)際進(jìn)行軟件開(kāi)發(fā)時(shí),程序會(huì)比較復(fù)雜,代碼量比較大,
一個(gè)程序按結(jié)構(gòu)至少可以劃分為三個(gè)文件:類的聲明文件(*.h文件)、類的實(shí)現(xiàn)文件(*.cpp文件)和主函數(shù)文件(使用到類的文件),如果程序更復(fù)雜,我們會(huì)為每個(gè)類單獨(dú)建一個(gè)聲明文件和一個(gè)實(shí)現(xiàn)文件。這樣我們要修改某個(gè)類時(shí)就直接找到它的文件修改即可,不需要其他的文件改動(dòng)。
雞啄米在第十九講中講生存期時(shí)有個(gè)時(shí)鐘類的例子,現(xiàn)在雞啄米給大家看下將那個(gè)程序按照上面說(shuō)的結(jié)構(gòu)分到三個(gè)文件里:
// 文件1:Clock類的聲明,可以起名為Clock.h
#include iostream
using namespace std;
class Clock //時(shí)鐘類聲明
{
public: //外部接口
Clock();
void SetTime(int NewH, int NewM, int NewS); //三個(gè)形參均具有函數(shù)原型作用域
void ShowTime();
~Clock(){}
private: //私有數(shù)據(jù)成員
int Hour,Minute,Second;
};
// 文件2:Clock類的實(shí)現(xiàn),可以起名為Clock.cpp
#include "Clock.h"
//時(shí)鐘類成員函數(shù)實(shí)現(xiàn)
Clock::Clock() //構(gòu)造函數(shù)
{
Hour=0;
Minute=0;
Second=0;
}
void Clock::SetTime(int NewH,int NewM,int NewS)
{
Hour=NewH;
Minute=NewM;
Second=NewS;
}
void Clock::ShowTime()
{
coutHour":"Minute":"Secondendl;
}
// 文件3:主函數(shù),可以起名為main.cpp
#include "Clock.h"
//聲明全局對(duì)象g_Clock,具有文件作用域,靜態(tài)生存期
Clock g_Clock;
int main() //主函數(shù)
{
cout"文件作用域的時(shí)鐘類對(duì)象:"endl;
//引用具有文件作用域的對(duì)象:
g_Clock.ShowTime();
g_Clock.SetTime(10,20,30);
Clock myClock(g_Clock); //聲明具有塊作用域的對(duì)象myClock,并通過(guò)默認(rèn)拷貝構(gòu)造函數(shù)用g_Clock初始化myClock
cout"塊作用域的時(shí)鐘類對(duì)象:"endl;
myClock.ShowTime(); //引用具有塊作用域的對(duì)象
}
在vs2010中如何生成這三個(gè)文件呢?我們可以點(diǎn)菜單中Project-Add Class,在彈出的對(duì)話框中選擇c++ class,然后由彈出個(gè)對(duì)話框,在class name處填上類名點(diǎn)finish就可以了,這樣.h文件和.cpp文件會(huì)自動(dòng)生成,我們也可以點(diǎn)Project-Add New Item,在彈出的對(duì)話框中選擇Header File(.h)或C++ File(.cpp)來(lái)生成.h文件或.cpp文件。
Clock.cpp和main.cpp都使用#include "Clock.h"把類Clock的頭文件Clock.h包含進(jìn)來(lái)。#include指令的作用就是將#include后面的文件嵌入到當(dāng)前源文件該點(diǎn)處,被嵌入的文件可以是.h文件也可以是.cpp文件。如果不包含Clock.h,Clock.cpp和main.cpp就不知道Clock類的聲明形式,就無(wú)法使用此類,所以所有使用此類的文件都應(yīng)該包含聲明它的頭文件。關(guān)于#include指令下面雞啄米會(huì)講。
上面的程序在編譯時(shí),由Clock.cpp和Clock.h編譯生成Clock.obj,由main.cpp和Clock.h編譯生成main.obj,然后就是鏈接過(guò)程,Clock.obj和main.obj鏈接生成main.exe可執(zhí)行文件。如果我們只修改了類的實(shí)現(xiàn)文件,那么只需重新編譯Clock.cpp并鏈接就可以,別的文件不用管,這樣就提高了效率。在Windows系統(tǒng)中的C++程序用工程來(lái)管理多文件結(jié)構(gòu),而Unix系統(tǒng)一般用make工具管理,如果大家從事Unix系統(tǒng)軟件開(kāi)發(fā),就需要自己寫make文件。
二.編譯預(yù)處理程序
編譯器在編譯源程序以前,要由預(yù)處理程序?qū)υ闯绦蛭募M(jìn)行預(yù)處理。預(yù)處理程序提供了一些編譯預(yù)處理指令和預(yù)處理操作符。預(yù)處理指令都要由“#”開(kāi)頭,每個(gè)預(yù)處理指令必須單獨(dú)占一行,而且不能用分號(hào)結(jié)束,可以出現(xiàn)在程序文件中的任何位置。
1.#include指令
#include指令也叫文件包含指令,用來(lái)將另一個(gè)源文件的內(nèi)容嵌入到當(dāng)前源文件該點(diǎn)處。其實(shí)我們一般就用此指令來(lái)包含頭文件。#include指令有兩種寫法:
#include 文件名
使用這種寫法時(shí),會(huì)在C++安裝目錄的include子目錄下尋找中標(biāo)明的文件,通常叫做按標(biāo)準(zhǔn)方式搜索。
#include "文件名"
使用這種寫法時(shí),會(huì)先在當(dāng)前目錄也就是當(dāng)前工程的目錄中尋找""中標(biāo)明的文件,若沒(méi)有找到,則按標(biāo)準(zhǔn)方式搜索。
2.#define和#undef指令
如果你學(xué)過(guò)C語(yǔ)言,就會(huì)知道用#define可以定義符號(hào)常量,比如,#define PI 3.14 這條指令定義了一個(gè)符號(hào)常量PI,它的值是3.14。C++也可以這樣定義符號(hào)常量,但一般更常用的是在聲明時(shí)用const關(guān)鍵字修飾。C語(yǔ)言還用#define定義參數(shù)宏,來(lái)實(shí)現(xiàn)簡(jiǎn)單的函數(shù)運(yùn)算,比如,#define add(x,y) (x+y) 這條指令說(shuō)明如果我們用到add(1,2)則預(yù)處理后就會(huì)用(1+2)代替,C++中一般用內(nèi)聯(lián)函數(shù)來(lái)實(shí)現(xiàn)。
#undef用來(lái)刪除由#define定義的宏,使其不再起作用。
3.條件編譯指令
用條件編譯指令可以實(shí)現(xiàn)某些代碼在滿足一定條件時(shí)才會(huì)參與編譯,這樣我們可以利用條件編譯指令將同一個(gè)程序在不同的編譯條件下生成不同的目標(biāo)代碼。例如,我們可以在調(diào)試程序時(shí)加入一些調(diào)試語(yǔ)句,用條件編譯指令控制只有在debug模式下這些調(diào)試語(yǔ)句才參與編譯,而在release模式下不參與編譯。
條件編譯指令有5中形式:
a.第一種形式:
#if 常量表達(dá)式
程序正文 //當(dāng)“ 常量表達(dá)式”非零時(shí)本程序段參與編譯
#endif
b.第二種形式:
#if 常量表達(dá)式
程序正文1 //當(dāng)“ 常量表達(dá)式”非零時(shí)本程序段參與編譯
#else
程序正文2 //當(dāng)“ 常量表達(dá)式”為零時(shí)本程序段參與編譯
#endif
c.第三種形式:
#if 常量表達(dá)式1
程序正文1 //當(dāng)“ 常量表達(dá)式1”非零時(shí)本程序段參與編譯
elif 常量表達(dá)式2
程序正文2 //當(dāng)“常量表達(dá)式1”為零、“ 常量表達(dá)式2”非零時(shí)本程序段參與編譯
...
elif 常量表達(dá)式n
程序正文n //當(dāng)“常量表達(dá)式1”、...、“常量表達(dá)式n-1”均為零、“ 常量表達(dá)式n”非零時(shí)本程序段參與編譯
#else
程序正文n+1 //其他情況下本程序段參與編譯
#endif
d.第四種形式:
#ifdef 標(biāo)識(shí)符
程序段1
#else
程序段2
#endif
如果“標(biāo)識(shí)符”經(jīng)#defined定義過(guò),且未經(jīng)undef刪除,則編譯程序段1,否則編譯程序段2。
e.第五種形式:
#ifndef 標(biāo)識(shí)符
程序段1
#else
程序段2
#endif
如果“標(biāo)識(shí)符”未被定義過(guò),則編譯程序段1,否則編譯程序段2。
4.define操作符
define是預(yù)處理操作符,不是指令,所以不能用#開(kāi)頭。使用形式為:define(標(biāo)識(shí)符)。如果括號(hào)里的標(biāo)識(shí)符用#define定義過(guò),并且沒(méi)有用#undef刪除,則define(標(biāo)識(shí)符)為非0,否則為0。可以這樣使用:
#if !define(HEAD_H)
#define HEAD_H
我們?cè)诎^文件時(shí),有時(shí)多次重復(fù)包含同一個(gè)頭文件,比如下面這種情況:
// main.cpp文件
#include "file1.h"
#include "file2.h"
int main()
{
…
}
// file1.h文件
#include "head.h"
…
// file2.h文件
#include "head.h"
…
// head.h文件
...
class A
{
...
}
...
main.cpp包含了file1.h文件,file1.h又包含了head.h文件,main.cpp還包含了file2.h文件,file2.h也包含了head.h文件,那么main.cpp就包含了兩次head.h文件,在編譯時(shí)就會(huì)報(bào)錯(cuò),說(shuō)head.h中的類A重復(fù)定義了。這時(shí)我們可以在被重復(fù)包含的文件head.h中使用條件編譯指令,用一個(gè)唯一的標(biāo)識(shí)符來(lái)標(biāo)識(shí)head.h文件是否已經(jīng)編譯過(guò),如果已經(jīng)編譯過(guò)則不會(huì)重復(fù)編譯了。雞啄米給大家改寫下上面的head.h文件:
// head.h文件
#ifndef HEAD_H
#define HEAD_H
...
class A
{
...
}
...
#endif
在這個(gè)改好的head.h文件中,上來(lái)會(huì)先判斷HEAD_H是否被定義過(guò),如果沒(méi)有被定義過(guò),則head.h文件還沒(méi)參與過(guò)編譯,就編譯此文件中的源代碼,同時(shí)定義HEAD_H,標(biāo)記head.h文件已經(jīng)參與過(guò)編譯。如果HEAD_H已經(jīng)被定義過(guò),則說(shuō)明此文件已經(jīng)參與過(guò)編譯,編譯器會(huì)跳過(guò)本文件左右內(nèi)容編譯其他部分,類A也不會(huì)有重復(fù)定義的錯(cuò)誤了。
題目明顯提示你沒(méi)有定義“add”呀,要求你查看“add”哦!再個(gè)你程序還是有問(wèn)題的吧,如果你把它放到不同的源文件中一起編譯連接的話,還會(huì)出現(xiàn)重復(fù)定義的錯(cuò)誤吧。改正如下:
#includestdio.h
#includemalloc.h
struct add *wwe();
struct add
{
int xuehao;
};
main()
{
struct add *p1;
p1=wwe();
}
//被調(diào)函數(shù)332.c
#include stdio.h
#includemalloc.h
struct add *wwe() //此處你是定義一個(gè)名為wwe的函數(shù),沒(méi)有參數(shù),返回值類型是:struct add*
{
struct add *p1;
p1=(struct add *)malloc(sizeof(struct add)); /*此處“extern”可以不要吧,一般他是用來(lái)聲明用的,*/
return p1; //此處要返回一個(gè)值,沒(méi)有值是不可以的
}
你只要明白一個(gè)原理就可以了:即 “..\”表示你編輯的當(dāng)前文件的路徑向上一級(jí)目錄。比如 File1 文件夾里面有一個(gè)文件test.h 和另一個(gè)文件夾File2 ,F(xiàn)ile2又有一個(gè)文件test.c,你如果想在test.c這個(gè)文件里面引用test.h這個(gè)文件,只要在test.c這個(gè)文件這樣引用:#include "..\test.h"即可
首先要建立一個(gè)頭文件,以.h保存
這樣
#include stdio.h
typedef struct {
char name[100][60];
char number[100][8];
int mon[100],day[100];
char sex[100];
double height[100];
}inf;
int input(inf *x ,int i);
int output(inf *y ,int h);
當(dāng)然要有個(gè)主函數(shù).
#include "inout.h"
int main(void)
{
int n;
inf id;
do{
printf("*********n");
scanf("%d",n);
}while(n100);
input(id,n);
output(id,n);
return(0);
}
然后 這個(gè)頭文件有兩個(gè)函數(shù).這兩個(gè)函數(shù),以.c的格式保存.
#include stdio.h
#include "inout.h"
int input(inf *x,int i)
{
........
}
#include stdio.h
#include "inout.h"
int output(inf *y ,int h)
{
....
}
主函數(shù)來(lái)負(fù)責(zé)調(diào)用,別的源文件.但是,要有一定要有個(gè)頭文件.
就相當(dāng)說(shuō), 站長(zhǎng)(主函數(shù))要控制各個(gè)列車(多個(gè)源文件).需要通過(guò)調(diào)度臺(tái)(頭文件)
這是我的理解,我也是剛學(xué).希望大家指正
編譯的時(shí)候,要分別編譯,先要把非主函數(shù)的源文件便宜成obj格式.
我的編譯器是:cl /c 源文件名.c (cygwin中是 gcc -c 源文件名.c)
最后和主函數(shù)結(jié)合.
cl main.c 源文件.obj
cygwin中是 gcc -o main main.c 源文件.o
不知道 我說(shuō)的夠不夠明白
函數(shù)應(yīng)該就是接口了 函數(shù)返回值 函數(shù)名和函數(shù)參數(shù) c語(yǔ)言可以寫dll可以把其中的函數(shù)導(dǎo)出
在調(diào)用函數(shù)之前,編譯器需要知道調(diào)用的規(guī)則,即調(diào)用的參數(shù)、參數(shù)個(gè)數(shù)、返回值,以一個(gè)文件為單位。
比如在first.c中需要調(diào)用play1那么編譯器就需要買哦時(shí)play1的調(diào)用規(guī)則,所以一般用int play1();這樣的語(yǔ)句說(shuō)明一下,用extern也可以,由于main中不存在調(diào)用play2的語(yǔ)句,就不需要事先聲明了;
在second.c中由于play1之前編譯器已經(jīng)編譯過(guò)了play2,所以知道了play2的調(diào)用規(guī)則,就可以省略聲明語(yǔ)句。
象first.c中調(diào)用外部程序比較多時(shí),就將這些聲明語(yǔ)句另存成一個(gè).h文件,然后用include包含這個(gè).h文件就可正常調(diào)用了,例如#includestdio.h
網(wǎng)站名稱:c語(yǔ)言多文件函數(shù)接口,c多文件編程
分享URL:http://chinadenli.net/article1/dsgpeod.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化、網(wǎng)站導(dǎo)航、移動(dòng)網(wǎng)站建設(shè)、全網(wǎng)營(yíng)銷推廣、網(wǎng)站制作、定制開(kāi)發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)