首先main是执行的入口,进入main才可以执行,main之外的都是一些全局变量或是函数的定义。
c函数把每一个文件当作一个module对待,既然每一个文件就是一个模块(这个跟paython很像奥),那么模块势必有私有的属性方法和对外提供的属性方法,在c语言中一个文件中的变量和方法如果被extern修饰,那么这说明这个变量是引用的外部的模块的变量,通俗说这个变量就是起码两个模块间的通用变量,如果用static来修饰那么这个变量就是本模块自身的与其他模块不通用。连接器一旦在某一个模块发现一个不被static修饰的变量a,就把他标注在导出符号表中,再在别的模块遇到不被static修饰的a,那么这个a被视为与存在于导出表中的a是一个变量。因此在不同的模块中重复定义单一赋值一个变量按道理是应该被允许的,但是重复赋值就不妙了,因为编译器不能确定哪一个值是准确的值。编译的时候,每一个模块都作为一个独立的个体存在,因此地址可能都是从0x0000开始的,很明显我们需要为每一个模块设置一个偏移量,以确保不同模块中的变量不会地址覆盖,当然了extern的外部变量是不能受本模块的偏移地址影响,他来自哪一个模块就要受那个模块的偏移地址影响。说白了就是当前地址+偏移地址得到一个新地址。
对于.h的由来,猜测一下哈,假设我们写了一个文件a.c里面定义了很多变量,然后我们在b.c中需要用到这些变量,要知道c规定必须先定义才能用啊,虽然a,b我们最终会连接在一起,按道理在一个里面声明了就行了,但是不行,c语言规定变量用之前必须先声明,如果用别的模块的externxx,当然了这个extern可以省略,所以啊我们最终把声明给提取出来,注意按道理讲这个.h中不应该赋值,这是中规范。
具体的原理以后再陆续补上,当下有些累。