C语言作用域和链接属性

一.作用域

当变量被定义在程序不同位置时,它的作用范围是不一样的,这个作用范围就是我们所说的作用域。

C语言编译器可以确认4种不同类型的作用域:

——代码块作用域

——文件作用域

——原型作用域

——函数作用域

1.代码块作用域

在代码块中定义的变量,具有代码块作用域。作用范围是从变量定义的位置开始,到标志该代码块结束的右大括号{}处

尽管函数的形式参数不在大括号内定义,但同样具有代码块作用域,隶属于包含函数体的代码块

复制代码
#include <stdio.h>

int main(void)
{
    int i = 100; // i1
    {
        int i = 110; // i2
        {
            int i = 120; // i3
            printf("i = %d\n", i);
        }
        // i = 110
        {
            printf("i = %d\n", i);
            int i = 130; // i4
            printf("i = %d\n", i);
        }
        printf("i = %d\n", i);
    }
    printf("i = %d\n", i);

    return 0;
}
复制代码

 

 

2.文件作用域

任何在代码块之外声明的标识符都具有文件作用域,作用范围是从它们的声明位置开始,到文件的结尾处都是可以访问的。

另外,函数名也具有文件作用域,因为函数名本身也是在代码块之外。

复制代码
#include <stdio.h>

void func(void);

int main(void)
{
    extern int count;

    func();
    count++;
    printf("In main, count = %d\n", count);    

    return 0;
}

int count;

void func(void)
{
    count++;
    printf("In func, count = %d\n", count);
}
复制代码

 

3.原型作用域

原型作用域只适用于那些在函数原型中声明的参数名。函数在声明的时候可以不写参数的名字(但参数类型是必须是写上的),其实函数原型的参数名还可以随便写一个名字,不必与形式参数相匹配。

void func(int a,int b,int c);
void func(int d,int e, int f)
{
....
}

4.函数作用域

函数作用域只适用于goto语句的标签,作用将goto语句的标签限制在同一个函数内部,以及防止出现重名标签

二.定义和声明

当一个变量被定义的时候,编译器为变量申请内存空间并填充一些值。
当一个变量被声明的时候,编译器就知道该变量被定义在其他地方。
声明是通知编译器该变量名及相关的类型已存在,不需要再为此申请内存空间。
局部变量既是定义又是声明。
定义只能来一次,否则就叫做重复定义某个同名变量;而声明可以有很多次。

三.链接属性

1.external(外部的)
多个文件中声明的同名标识符表示同一个实体
internal(内部的)
单个文件中声明的同名标识符表示同一个实体
none(无)
声明的同名标识符被当作独立不同的实体

2.只有具备文件作用域的标识符才能拥有external或internal的链接属性,其他作用域的标识符都是none属性。
默认情况下,具备文件作用域的标识符拥有external属性。也就是说该标识符允许跨文件访问。对于external属性的标识符,无论在不同文件中声明多少次,表示的都是同一个实体。
 
3.使用static关键字可以使得原先拥有external属性的标识符变为internal属性。这里有两点需要注意:
使用static关键字修改链接属性,只对具有文件作用域的标识符生效(对于拥有其他作用域的标识符是另一种功能)
链接属性只能修改一次,也就是说一旦将标识符的链接属性变为internal,就无法变回external了
 

 

 编译器工作原理:https://fishc.com.cn/forum.php?mod=viewthread&tid=78063&extra=page%3D1%26filter%3Dtypeid%26typeid%3D571

 

 

posted @   清歌牧言  阅读(1601)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示