#define 、#include 等在预处理阶段处理,而在编译时已经不存在了,所以它们不是关键字
#include “math.h” 仅在当前路径查找math.h文件
#include <math.h> 在标准库路径下查找此文件
宏定义
优势:原地展开,没有调用开销;并且在预处理阶段完成,不占用编译的时间
缺点:不进行类型检查,实际传参和宏所希望的参数类型必须一致,否则可能出现编译不报错但是运行有误
无参宏定义:
#define 宏名 宏体(为安全起见,加括号)
eg:#define ABC 5+3
printf("The %d \n",ABC*5); // 5+3*5 若加括号:(5+3)*5
带参宏定义:
eg:#define MAX(a,b) (((a)>(b)) ? (a):(b))
带参函数与带参宏定义的对比:
函数是编译期间处理的,在调用函数(用栈来做支持,调用一次就会进行一次压栈)处跳转到函数中去执行,跳转执行完再返回,有比较大的调用开销。
宏定义是预编译期间原地展开,没有调用开销,没有传参开销,函数体很短时可以用宏定义来替代,提高效率
内联函数:
内联函数本身是函数,所以编译器会进行参数的静态类型检查;同时内联函数原地展开,没有调用开销
内联函数 —— C 中关键字 inline 用法解析
编译的过程:
GCC编译指令:
命令格式:gcc [选项] [文件名]
编译的四个阶段:
-E:仅执行编译预处理;
-c:仅执行编译操作,不进行连接操作;
-S:将C代码转换为汇编代码;
-o:指定生成的输出文件;
- I:指定查找头文件的目录。
编译预处理涉及的内容
文件包含:#include <xxx> #include " xxx"
宏定义:宏定义在预处理阶段由预处理器进行原封不动的替换(替换会递归进行,直到替换出来的值不是宏为止)
条件编译:在源代码级别去修改配置开关来让程序编译出不同的结果
去掉程序中的注释:移除所有的注释有一个空格替换
GCC编译工具链:包括预处理器、编译器、汇编器、链接器
GCC一步到位编译为可执行文件: gcc test.c -o test 或者 gcc -o test test.c
GCC进行编译链接的过程:四个步骤
1、预处理 gcc -E test.c -o test.i
2、编译为汇编文件 gcc -S test.i (.c) -o test.s
3、汇编为目标文件 gcc -c test.s -o test.o
4、链接为可执行文件:gcc text.o -o text
执行 ./test 即可输出程序执行结果
带库文件连接的gcc编译指令
eg: gcc -c -I /usr/dev/mysql/include test.c -o test
//countlib.c
#include<stdio.h>
unsigned long count(unsigned int a,unsigned int b)
{
return a*b;
}
//count.c
#include<stdio.h>
#include<stdlib.h>
int main(int argc,char *argv[])
{
unsigned int x,y;
sscanf(argv[1],"%u",&x);
sscanf(argv[2],"%u",&y);
printf("result is : %u\n",count(x,y));
return 0;
}
//编译静态链接库:
binge@ubuntu14:~/user$ gcc -c countlib.c -o countlib.o
binge@ubuntu14:~/user$ ls
count.c countlib.c countlib.o hello hello2 hello.c hello.o my_share
binge@ubuntu14:~/user$ ar crv countlib.a countlib.o
a - countlib.o
binge@ubuntu14:~/user$ ls
count.c countlib.a countlib.c countlib.o hello hello2 hello.c hello.o my_share
binge@ubuntu14:~/user$ gcc -o count count.c -L./ countlib.a
binge@ubuntu14:~/user$ ./count 10 20
result is : 200
//编译动态链接库:
binge@ubuntu14:~/user$ gcc -fPIC -c countlib.c
binge@ubuntu14:~/user$ ls
count count.c countlib.a countlib.c countlib.o hello hello2 hello.c hello.o my_share
binge@ubuntu14:~/user$ gcc -shared countlib.o -o countlib.so
binge@ubuntu14:~/user$ ls
count count.c countlib.a countlib.c countlib.o countlib.so hello hello2 hello.c hello.o my_share
binge@ubuntu14:~/user$ gcc -o count2 count.c -L./ countlib.so
binge@ubuntu14:~/user$ ./count2
./count2: error while loading shared libraries: countlib.so: cannot open shared object file: No such file or directory
binge@ubuntu14:~/user$ sudo cp countlib.so /usr/lib
[sudo] password for binge:
binge@ubuntu14:~/user$ ./count2 10 9
result is : 90
注:默认情况下,GCC都是采用动态链接库的,因此生成的可执行文件小了很多。可以使用-static强制进行静态链接,不过可执行文件就会很大。
强制静态链接,如:gcc hello.c -static -o hello