由於在C語言中,不能把所有的代碼都放在一個.c文件里面,這樣這個.c文件會很大,而且代碼維護起來會很麻煩。
於是在網上找了些C語言多文件編程的示例,記錄下我的學習過程。
我們可以把我們的代碼按功能進行划分,一些源文件存放函數的實現,一些頭文件聲明這些函數,這樣代碼會更有條理。
頭文件的大致格式:(注意,頭文件中一般只能有申明,不能有定義,否則會出現重定義錯誤——multiple definition of。。。)
#ifndef _ABC_H_ #define _ABC_H_ //以上代碼是為了防止這個頭文件被多次包含,確保名字唯一 //宏定義 #define _MAX 100 //結構體聲明 typedef struct{ int a; }ABC; //函數聲明 extern void abcfun(void); ... #endif
在寫頭文件的時候,有一點需要特別的注意,(一般情況下)定義不能放在頭文件里面,需要放在一個單獨的c文件里面,頭文件里面只能有一個申明,如: extern Type A。
要對以上要求進行解釋,我們需要了解編譯的過程:
編譯的第一步是把所有的CPP文件編譯成為點O文件,而且每一個點CPP文件都是單獨編譯的,該點CPP文件中用到的類型必須在它所include 的頭文件當中找到,相當於把它所有include的文件中的代碼都加到該CPP文件的前面,
但是聲明的部分將不會出現在編譯后的點O文件,相當於每個 CPP文件都是單獨編譯,因此它的ifndef在一個文件里是沒有用的,兩個CPP文件里如果包含同一個有ifndef的頭文件,效果是兩個CPP文件都 把該頭文件加到它的前面,但不會把聲明的部分放到點O文件中,而會把頭文件中定義的部分都輸出到編譯后的點O文件當中,因此如果在頭文件當中有一個定義,那么如果有兩個CPP文件當中include了它,那么將會出現重定義錯誤,multiple definition of
接下來介紹下多文件編程的小例子
功能:在main.c里面調用其他兩個源文件里面的函數,然后輸出字符串。
1、main.c
#include"mytool1.h" #include"mytool2.h" int main(int argc,char* argv[]) { mytool1_printf("hello."); mytool2_print("hello"); return 1; }
2、 mytool1.h mytool1.c
//mytool1.h #ifndef _MYTOOL_1_H #define _MYTOOL_1_H void mytool1_printf(char* print_str); #endif //mytool1.c #include"mytool1.h" #include<stdio.h> void mytool1_printf(char* print_str) { printf("This is mytool1 print %s\n",print_str); }
3、 mytool2.h mytool2.c
//mytool2.h #ifndef _MYTOOL_2_H #define _MYTOOL_2_h void mytool2_print(char* print_str); #endif //mytool2.c #include "mytool2.h"
#include<stdio.h> void mytool2_print(char* print_str) { printf("This is mytool2 print %s\n",print_str); }
在linux下,把這幾個文件放在同一個目錄下,然后在shell中輸入
gcc -c main.c gcc -c mytool1.c gcc -c mytool2.c gcc main.o mytool1.o mytool2.o -o main
就可以生成可執行文件 main
關於 Makefile
如果項目中的源文件改動一次,那項目就要重新編譯一次,這樣會很麻煩。一個Makefile文件就可以解決這個問題。Makefile文件里面存在編譯的指令,這樣源文件改變一次,我們只要重新Make一下,項目就會編譯好,會很方便。
cc=gcc target=main obj=main.o mytool1.o mytool2.o $(target):$(obj) $(cc) $(obj) -Wall -o $(target) main.o:main.c $(cc) -c main.c mytool1.o:mytool1.c $(cc) -c mytool1.c mytool2.c:mytool2.c $(cc) -c mytool2.c .PHONY:clean $(RM) *.o $(target)
引用:
http://blog.163.com/m13591120447_1/blog/static/21637918920132365724538/
http://soft.chinabyte.com/os/12/11584512.shtml