编译链接过程:
预编译:删除所有的“define”,删除注释,并展开所有的宏定义
处理所有的条件预编译指令“#if”“#ifdef”“endif”等
处理“include”预编译指令,被包含的文件插入到该预编译指令的位置
删除行号和文件名标识,以便于编译器产生调试用的符号信息及编译时产生编译错误和警告时显示的行号
保留所有的#pragma编译指令,因为编译器需要使用它们编译:词法分析
语法分析
语义分析
代码优化
符号汇总汇编:将编译指令翻译成二进制格式,
生成各个section
生成符号表链接:合并各个section,调整section的起始位置和段大小
合并符号表,进行符号解析
符号重定位
objump:查看中间文件
readelf:查看可执行文件
.o文件为可重定位的二进制目标文件(中间文件)
库文件:
库文件:预先编译好的方法的集合,提前写好的一些公式的实现,打包成库文件,使用库文件即可,不需要重新编写
库文件的链接:gcc -o main main.c -L路径 -l库名
库文件分类:静态库
共享库(动态库)静态库特点:程序在链接的过程中,链接器从库文件中取得所需代码。复制到生成的可执行文件中,因此静态库是在程序的链接阶段被复制到程序中的,和程序的执行过程没有关系
动态共享库特点:动态库在链接阶段并没有被加载到进程中,而进程在运行时被系统动态绑定加载到内存中供内存使用静态库实现命令:
ar crv libxxx.a file 例如:ar crv libmain.a main.c max.o libmain.a即为静态库
动态库实现命令:
gcc -shared -fPIC -o libxxx.so file
1、gcc -c -fPIC file 2、gcc -shared -o libxxx.so file libxxx.so即为动态库操作系统加载动态库时默认搜索两个路径: /lib /usr/lib
export LD_LIBRARY_PATH 共享库的绝对路径
编辑/home/user/bashrc:设置LD_LIBRARY_PATH静态库与动态库的区别:
静态库的可执行文件中包含了裤库代码的一份完整的拷贝,因此当它被所次使用时就会有多份无用的拷贝在内存当中,所以比较占内存,而动态库系统只载入一次动态库,不同的程序可以得到内存当中相同的动态库副本,因此会节省很多空间
makefile:
makefile主要包括五方面的内容:显示规则、隐晦规则、变量定义、文件指示和注释
makefile规定了我们编译链接的流程、先后顺序及依赖关系
makefile关系到整个工程的编译规则,可以执行操作系统的命令,实现自动化编译整个文件工程,提高编译效率
特点:一次编译、、永久使用,且当文件修改后,只编译修改和依赖于修改的文件的文件make是命令,makefile使文件,栈式编程规则
虚拟机链接U盘:将U盘与windows断开,虚拟机中找到可移动设备,su root,切换到root用户下,
在/mnt中创建usb子目录,df 查看U盘对应的设备接口,
mount /dev/设备接口 /mnt/usb(挂载),umount /dev/设备接口(卸载)main函数:int main(int argc,char *argv[],char *envp[])
argc:参数个数
argv:参数列表
envp:环境变量printf:输出缓冲区
scanf:输入缓冲区
输出缓冲区刷新的条件:
1、遇到回车
2、程序结束
3、主动刷新 fflush(stdout)
4、缓冲区满 1024byte_exit(int)和exit(int):exit结束 进程时会刷新缓冲区,_exit直接结束释放空间,不刷新缓冲区