C语言(五)extern和static关键字

来源:互联网 发布:单身狗 知乎 编辑:程序博客网 时间:2024/05/17 03:33

一、extern与函数

    如果一个程序由多个源文件,编译成功后会生成对应的多个目标文件,这些目标文件还不能单独运行,因为这些目标文件之间可能会有关联,比如:a.obj文件可能会调用c.obj中定义的一个函数。将这些相关的目标文件链接在一起后生成可执行文件
1.外部函数和内部函数
1)外部函数:如果在当前文件中定义的函数允许在其它文件访问、调用,就称为“外部函数”。C语言规定,不允许有同名的外部函数。
2)内部函数:如果在当前文件中定义的函数只能在内部使用,就称为“内部函数”。C语言对顶不同的源文件可以有同名的内部函数,并不互相干扰。

2.外部函数
    因为所有的函数默认就是外部函数,所以extern关键字和auto一样,就是废的。
    常见的做法:
    ①创建one.c文件,在里面定义一些函数。
    ②创建one.h文件,在里面对one.c定义的函数进行声明。
    ③在main.c文件中,包含one.h头文件即可使用里面的函数。

3.外部函数使用例子

one.c

#include <stdio.h>void one(){printf("this is method one()\n");}void two(){printf("this is method two()\n");}void three(){printf("this is method three()\n");}
one.h

#ifndef __C__one_h#define __C_one_hvoid one();void two();void three();#endif
first.c

#include <stdio.h>#include "one.h"int main(){one();two();three();return 0;}

执行指令:
    gcc -c first.c one.c
    gcc first.o one.o -o first.exe
    first.exe
执行结果:


二、static与函数

1.定义内部函数
    从上面的例子看出,one.c中定义的函数时可以被其他源文件访问的。其实有时候,我们想定义一个“内部函数”,不能被其他源文件访问的函数。只需使用static关键字修饰函数即可。
备注:
1)将上面的one函数用static关键字修饰一下,发现在链接的时候报错。
2)在编译阶段:编译器只检测单个源文件的语法是否不合理,并不测函数有没有定义;只有在链接的时候才会检测这个函数存不存在,也就是有没有被定义。
3)所谓编译:
    就是单独检查每个源文件的语法是否合理,并不检查每个源文件之间的关联关系,一个源文件编译成功后就会生成一个目标文件。
  所谓链接:就是检查目标文件的关联关系,将相关联的目标文件组合在一起,生成可执行文件。

2.声明和定义内部函数
#include <stdio.h>static void test();int main(int argc, const char * argv[]){    test();    return 0;}static void test() {    printf("调用了test函数");}


三、static 、extern与函数的总结

1.static 
    在定义函数时,用static关键字进行修饰。内部函数又称为“静态函数”。这样该函数只能够在其定义的文件中使用,如果在不同的文件中有同名的外部函数,则互不干扰。

2.extern
    使用extern关键字修饰的函数,就是外部函数,可以省略。默认定义的函数就是外部函数。
    一个文件中想要调用其它文件中的外部函数,则需要再当前文件中使用extern声明该函数,然后就可使用,extern也可以省略。

四、static/extern与变量

1.全局变量的位置
    在java中全局变量的位置是没有要求的。但是在C语言中,全局变量定义的位置是有限制的。默认一个函数不能访问在它后面定义的全局变量。
    解决方法:
        方法一:将全局变量定义到前面。
        方法二:在前面用extern进行声明。

2.重复定义同一个变量
    在C语言中,可以重复定义某个变量,它们始终代表的是同一个变量。
#include <stdio.h>int a=10;int main(){extern int a;    //表示引用全局变量,其实是多次一举,这行是多余的a=12;            //为全部变量重新赋值printf("%d\n",a);return 0;}int a; //执行成功

#include <stdio.h>int a=10;//全局变量int main(){int a =12;//局部变量,和全部变量a之间没有任何关系printf("%d\n",a);return 0;}int a;
3.不同源文件中的同名变量
    在2个源文件中定义同一个变量,它们代表的都是同一个变量。
one.c
#include <stdio.h>int a; void one(){printf("%d\n",a);}
first.c

#include <stdio.h>int a ;void one();int main(){a =12;one();return 0;}

4.extern关键字
    必须有已经声明过变量,才能使用extern关键字引用该变量。
    例如:one.c中定义int a;在main.c中引用该变量,extern int a
    但是不允许两边都使用extern修饰,因为都没定义,如何引用。

5.static
    私有的全部变量:使用static关键字修饰的变量。该变量只能在该源文件内有效。

6.总结
1)extern可以用来引入一个全局变量。
2)默认情况下,一个变量是可以供多个源文件共享的,也就是说,多个源文件中同名的全局变量都代表着同一个变量。
3)如果在定义全局变量的时候加上static关键字,那么该全局变量仅限于定义该变量的源文件。与其它源文件中的同名变量互不干扰。








0 0