C语言之编译过程

#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

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值