C语言__static和extern关键字
static和extern不仅可以用在变量上,还可以用在函数上。这讲先介绍它们对函数的作用。
extern与函数
如果一个程序中有多个源文件(.c),编译成功会生成对应的多个目标文件(.obj),这些目标文件还不能单独运行,因为这些目标文件之间可能会有关联,比如a.obj可能会调用c.obj中定义的一个函数。将这些相关联的目标文件链接在一起后才能生成可执行文件。
外部函数:如果在当前文件中定义的函数允许其他文件访问、调用,就称为外部函数。C语言规定,不允许有同名的外部函数。
内部函数:如果在当前文件中定义的函数不允许其他文件访问、调用,只能在内部使用,就称为内部函数。C语言规定不同的源文件可以有同名的内部函数,并且互不干扰。
编译完成后需要连接后才能运行,连接外部函数就是此刻我们的问题,在C语言标准里面直接使用外部函数是报错的,因为函数并不知道你的这个外部函数在哪里声明定义的,当然不可能直接使用。
那么我们导入外部函数所在的文件可以吗?答案是不可以,文件包含仅仅只是相当于字符串拷贝,这样的后果就是我们产生了同名的外部函数,C语言不允许同名外部函数存在,不然在连接的时候就不知道该连接那个文件了。
正确的做法是我们在使用外部函数的时候在主函数前面声明外部函数就行了,声明外部函数: extern 函数名 (参数列表);但是这样做在大型的项目里面超级的麻烦,所以我们一般会定义一个头文件,然后在头文件当中声明外部函数,把文件包含在主程序内就可以了。需要了解的是extern关键字不写没关系,因为不写默认就是extern。
static与函数
声明内部函数
static void one(); // 就是声明one函数是个内部函数。
定义内部函数
static void one() // 定义了内部函数 也称之为静态函数 外部不可以使用
{
函数语句;
}
编译、链接解惑
所谓编译,就是单独检查每个源文件的语法是否合理,并不会检查每个源文件之间的关联关系,一个源文件编译成功就生成一个目标文件。
所谓链接,就是检查目标文件的关联关系,将相关联的目标文件组合在一起,生成可执行文件。
static、extern与函数的总结
* 在定义函数时,在函数的最左边加上static可以把该函数声明为内部函数(又叫静态函数),这样该函数就只能在其定义所在的文件中使用。如果在不同的文件中有同名的内部函数,则互不干扰。* static也可以用来声明一个内部函数
* 在定义函数时,如果在函数的最左边加上关键字extern,则表示此函数是外部函数,可供其他文件调用。C语言规定,如果在定义函数时省略extern,则隐含为外部函数。
* 在一个文件中要调用其他文件中的外部函数,则需要在当前文件中用extern声明该外部函数,然后就可以使用,这里的extern也可以省略。
static与全局变量
在Java中,全局变量的定义没有严格的位置规定
在C语言中,全局变量定义的位置是有限制的。默认情况下,一个函数不可以访问在它后面定义的全局变量。要么在main函数之前定义,要么在main函数之前声明(extern是用来声明一个已经定义过的变量。)
在另一个源文件中也有全局变量int a;,那么这两个源文件的所有全局变量int a;都代表着同一个变量。
在全局变量前加static修饰符这表明了该变量为静态全局变量,其他文件的函数不可以使用,只可以在本文件下使用。