C語言的編譯過程
預處理
- 把
include、define
引入或者定義的東西替換一下。
# cpp -o ***.i ***.c
gcc -E
編譯
- 編譯成彙編語言
# cc1 -o ***.s ***.c
gcc -S
彙編
# as -o ***.o ***.s
gcc -c
鏈接
# collect2 -o *** ***.o+...
gcc -o
C語言常見錯誤
預處理錯誤
#include “name”
:查找系統目錄及當前目錄#include <name>
: 只查找系統目錄
如果頭文件不在系統目錄和當前目錄,則會出現not find
的錯誤信息。
- 解決方案:
gcc -I
跟查找頭文件的目錄
編譯錯誤
- 語法錯誤:缺少; {}之類的
鏈接錯誤
undefined reference to `***(function)`
:尋找標籤(函數)是否實現了,鏈接時是否一起鏈接。multiple definition of `***(function)`
:多次實現了標籤(函數),重複。
預處理內容
包含頭文件
#include
宏
#define
宏名 宏體。預處理宏的時候不進行語法檢查。- 宏參數:
#define A(x) (2+(x))
條件預處理
#ifdef #else #endif
//test.c
_______________________________________________________
#include <stdio.h>
int main(){
#ifdef DEBUG
printf("%s \n", __FILE__);
#endif
printf("hello world!\n");
return 0;
}
_______________________________________________________
gcc -DDEBUG -o test test.c
./test
output:
test.c
hello world!
gcc -o test test.c
./test
output:
hello world!
預定義宏
__FUNCTION__
:函數名
__LINE__
:行號
__FILE__
:文件名
//test.c
_______________________________________________________
#include <stdio.h>
int main(){
printf("%s %s %d", __FUNCTION__, __FILE__, __LINE__);
return 0;
}
_______________________________________________________
output: main test.c 3
//test.c
_______________________________________________________
#include <stdio.h>
int fun(){
printf("%s %s %d", __FUNCTION__, __FILE__, __LINE__);
return 0;
}
int main(){
fun();
return 0;
}
_______________________________________________________
output: fun test.c 3
宏展開下的#、##
- #:字符串
- ##:連接符
#include "stdio.h"
#define A(x) #x
#define DAY(x) day##x
int main(){
int day1=10;
int day2=20;
printf(A(abc\n));
printf("day is %d\n", DAY(1));
return 0;
}
________________________________________________________
output:
abc
day is 10