首页 /  技术专区  /  C 宽屏模式 >

函数和全局变量的本文件作用域

1、 函数和全局变量的本文件作用域

1.1 本文件作用域的有效范围

从定义位置开始到文件结束。

a.c

int main(void)           //main的本文件作用域:从定义位置到文件末尾
{
    fun(g_var1, g_var2);
    return 0;
}

int g_var1 = 100;     //g_var的本文件作用域:从定义位置到文件末尾
int g_var2;

int fun(int a)        //fun的本文件作用域:从定义位置到文件末尾
{
    int var;            
    return var +a;
}

1.2 通过声明改变本文件作用域

在上面的例子中,如果我们想在main函数中使用g_var1、g_var2、fun的话怎么办?

(1)方法1

        挪到main的前面去。

(2)方法2

        在main前面进行声明,通过声明将作用域提前。

a.c

int g_var1;  
int g_var1; 
int g_var1; 
int g_var1; 
int g_var2;
int g_var2;
int g_var2;
int fun(int a);

int main(void)           
{
    fun(g_var1, g_var2);
}

int g_var1 = 100;    
int g_var2;

int fun(int a)        
{
    int var;            
    return var +a;
}

(3)定义与声明的关系

        定义与声明的关系,其实就是第1章中介绍的“强弱符号关系”。

我们知道,定义与声明的符号名是相同的,编译时同名符号必须进行统一,然后合并为一个。

在之前,我们详细介绍过强弱符号的统一规则,我们这里再回顾下。

1)谁是强符号,谁是弱符号

        · 函数定义:强符号

        · 函数声明:弱符号

        

        · 初始化了的全局变量:强符号,我们常将这种称为定义

        · 未初始化的全局变量:弱符号,我们常将这种称为声明

2)强弱符号的统一规则

(a)不能允许重复出现同名的强符号,但是允许重复出现有同名的弱符号

        · 在a.c中同时定义两个全局变量int a = 100,编译无法通过。

        · 在a.c中同时定义两个同名函数fun,也编译无法通过

        · 可以对全局变量和函数进行重复声明,因为声明是弱符号,允许同名弱符号重复


        以前学C时老师总是讲,声明可以重复,原因就来自于这里。

(b)有一个强符号,其它都是弱符号的话,只保留强符号,其它弱符号消失

        同名符号的作用域以最前面的那个符号为准,正是因为这点原因,放在最前面的声明才能提前作用域。

        所以声明虽然是弱符号,遇到强符号时消失了,但是它能够提前作用域。

(c)全都是弱符号的话,只留一个即可,其它全部消失

        比如a.c中的两个int g_var2都是弱符号,统一符号时只留其中一个,留哪一个由编译器决定。

        但是不管留哪一个,作用域范围以最前面的哪一个为准。

        同一个.c中的强弱符号统一,是在第二阶段编译时由编译器来完成的,而不同.c中的强弱符号统一,则是由第4阶段“链接”来完成的,这一点我们在第1章详细介绍过,后面介绍“链接域”时,还会再次讲到。


(4)声明全局变量的特殊例子

int g_var1;

int main(void)           
{
    extern int g_var1; //声明  
    g_var1 = 100;
}

int fun(int a)        
{
    int var;            
    return var +a;
}

int g_var1 = 100;

main函数中extern int g_var1这种的生命方式表示,g_var1只在main函数内有效,对后面的fun无效。

extern可以省略吗?

不能省,省了g_var1就变成main的自动局部变量了,extern表示这个全局变量来自于函数外部。

extern有好些用法,不同用法的含义不一样,在这里先了解下这种用法。

假如你只想在main中使用g_var1,不想让g_var1的作用域覆盖到fun函数,就可以使用这种方法,不过这种声明方式用的确实不多,但是在有些源码中可能会看见,这里需要了解下。

同样的,函数也可以进行类似的声明。

int main(void)           
{
    extern int fun(int a); //fun的声明。
    fun(g_var1, g_var2);
}

int fun(int a)        
{
    int var;            
    return var +a;
}

(5)局部变量有声明吗?

局部变量没有声明一说,以下做法时错误的。

int main(void)
{
    int a; //声明:错误用法
    a = a + 1;
    int a = 100;
}

说白了就是,对于局部变量来说,变量符号只能有一个,不允许同名符号重复出现。

同一个.c中,变量同名的问题

        1)全局变量

        (a)如果同名变量都是强符号,这会导致变量重复定义,编译时会报错。

        (b)如果同名的是弱符号,它只会改变符号的作用域,除此外没有影响

        2)局部变量

        不允许存在同名符号。



头像
0/200
图片验证码