广东省建设厅网站,网站建设约谈表态发言,域名备案备注怎么写,营销策划参考1#xff1a;C header files and compilation/linking 参考2#xff1a;计算机系统基础#xff08;一#xff09;袁春风 #xff08;符号链接部分#xff09; 我们现在有一个简单的工程#xff0c;有这么几个文件
1.t1.h
extern int x;void tt();t1.c
#include C header files and compilation/linking 参考2计算机系统基础一袁春风 符号链接部分 我们现在有一个简单的工程有这么几个文件
1.t1.h
extern int x;void tt();t1.c
#include t1.hint x;void tt(){x 100;
}
main.c
#include stdio.h
#include t1.hint main(){tt();printf(x %d\n,x);return 0;
}现在我们依次来看一下
头文件 和 C源文件 如何联系在一起多文件如何变成1个可执行目标文件
预处理组合头文件与包含它的C源文件
在32位Linux系统中。
我们执行gcc -E t1.c -o t1.i对源程序进行预处理将头文件包含进来。
所谓预处理就是将预编译命令处理掉比如把头文件的内容拷贝到C源文件中因此我们就能够理解.h和.c文件中全部变量的关系了我们看一下生成的文件内容
# 1 t1.c
# 1 built-in
# 1 command-line
# 31 command-line
# 1 /usr/include/stdc-predef.h 1 3 4
# 32 command-line 2
# 1 t1.c
# 1 t1.h 1
extern int x;void tt();
# 2 t1.c 2int x;void tt(){x 100;
}可以看到开始有一些记录的信息看起来应该是注释是一些说明性信息。
然后我们看到之前头文件的内容在这个文件里面了。如果你把它近似地看为一个源文件你就能大概理解全局变量声明和定义以及不要重复定义等。
对于main.c文件的预处理道理是一样的
然后我们将t1.i和main.i分别生成其可重定位目标文件最后链接起来就生成了可执行目标文件。
gcc -c t1.i -o t1.o # 生成可重定位目标文件
gcc -c main.i -o main.o # 生成可重定位目标文件
gcc -o main main.o t1.o # 链接生成可执行目标文件
./main # 运行可执行目标文件最后需要说明
对于函数的声明头文件声明、外部声明、内部声明与定义内部定义、外部定义
在c源文件中进行函数声明然后使用它在链接的时候这个声明的函数但未在该文件中定义链接器会自动在其他的可重定位目标文件中寻找其定义如果找到了就联系起来否则就报错。这就意味着所有的C源文件中的函数默认都是全局的你可以在模块1声明函数a然后调用它在模块2中定义函数a之后将两个模块链接起来生成可执行文件。
好吧每次都声明很麻烦所以我们在模块2对应的头文件声明然后模块1引入头文件这样我们就能够进行和之前一样的操作了你知道的头文件在预处理的时候会被包含进入源文件这样其实达到了和我们手动声明一样的效果。
如果你不想让函数是全局的那就加上static这样只有该源文件可以使用它了
对于变量的定义与初始化
局部变量只能在其{ }内使用static变量只能在本模块内使用全局变量全部都可以用 本模块定义外部定义extern
对于本模块使用的没得说就是只有这个源文件能够使用这个变量
只讨论全局变量。
extern变量不要初始化只声明即可任何初始化的全局变量全局范围内只能初始化1次可以定义n次但是最终内存空间中的就是初始化的内个变量的位置只有一个头文件一般包含函数声明全局变量的定义似乎没必要或者说不要在头文件定义全局变量。全局变量最好少出现出现一次也就够了在不同编译器下要求不一样。少用。 比如在Linux的gcc下不同C源文件可以出现多个int x弱符号但是Windows的VS下就不允许。
因此说使用全局变量最好
初始化全局变量只定义一次其他的模块如果要用就声明extern表示引用外部定义而不是再声明一个弱符号不是不行但是这样的话gcc能用VS就不能用不要在头文件定义全局变量头文件被多次包含的话…得定义多少次恐怖
注意
函数有
是否声明是否定义是否使用
对于任何模块必须先声明再使用声明之后可以不定义因为可以外部定义但是被声明被使用的函数必须有其定义。 要是声明之后没有使用也没有定义其实也行但是最好不要这样干太奇怪了
对于同一模块先定义再使用也可以但是不能先使用再定义顺序很重要。 变量有
是否定义是否初始化是否使用
然后还涉及到不同模块之间…