1.在工程目录创建一个 handC 的目录
、
创建 子目录
src 仅存储 C文件
inc 存储头文件
obj 存储编译后的对象文件
bin 存储连接后形成的库或执行文件
src中创建test.c文件
执行 编译操作
gcc -c src/test.c -o obj/test.o
执行链接操作
gcc obj/test.o -o bin/test_main
执行如下命令
https://www.linkedin.com/
echo $? 用来检测最近一次操作的返回。 通过 显示结果可以看出返回结果表示命令执行时一共存在几个参数,包含执行程序文件名本身。
将代码分离
gcc -c src/test.c -o obj/test.o
gcc -c src/param.c -o obj/param.o
gcc obj/param.o obj/test.o -o bin/test_main
如果 只执行 gcc obj/test.o - o bin/test_main
则会出现错误提示
错误原因 “_main”函数汇总,出现没有定义的符号,“_chk_param” 。这里的“_main”实际是main函数编译后形成的汇编函数。与C文件中的函数对应的汇编函数 名称是C函数名称前增加前缀“_”
链接器在链接时,需要对各个调用函数的指令设置具体的地址,否则机器执行时无法跳转到目标函数的有效起始位置。
回到代码中,在test.c中,包含了param.c中的函数接口声明。param.c中的函数现在只被test.c中的main函数调用,但以后也可能被其他C文件某个函数调用。如果在每个存在调用chk_param的C文件中都编写对chk_param 函数声明对代码,实在过于繁琐。
一种 合理的做法是使用C语言的#include 预编译命令。它可以将后续的文件名所对应的内容,插入当前位置。通常所插入内容存储为.h后缀的文件(头文件)
现在将上述代码函数声明放入一个名为param.h的文件中,并存储在inc目录下。
在test.c中include
执行编译链接操作:
gcc -c -Iinc src/test.c -o obj/test.o
这里多了一个 -Iinc ,它是头文件路径参数-I和头文件路径inc两个内容多合写。这样,编译器就会尝试在inc中寻找param.h
gcc -c src/param.c -o obj/param.o
gcc obj/param.o obj/test.o -o bin/test_main
一个基础的概念,C语言的编译链接并不针对头文件,而仅仅对C文件。头文件的引用是编译前的预编译处理完成的工作,不要把头文件看作一个C程序的基础组成,而应当理解成头文件的内容是C程序中C文件的组成内容。
上面例子里,可通过执行下面的命令查看预编译对引用文件的处理结果:
gcc -Iinc scr/test.c -E -P