博客
关于我
作用域、链接属性和存储类型
阅读量:416 次
发布时间:2019-03-06

本文共 1686 字,大约阅读时间需要 5 分钟。

重新认识C语言中的作用域、链接属性与存储类型

最近在研读《程序员的自我修养——链接、装载与库》时,脑海中不由自主地浮现出学习C语言时的那些摸索之路。尤其是当初对externstatic等关键字的理解,至今仍让人感到不自信。因此,我重新翻开了《C和指针》中关于作用域、链接属性和存储类型的相关内容,并结合自己的理解,整理出一篇技术博客。

一、作用域

作用域是程序中标识符可以被访问的区域。它的大小和范围,直接关系到代码的可维护性和调试难度。在编译原理中,编译器会在语义分析阶段检查变量的作用域是否符合规则。

代码块作用域

代码块作用域是最常见的作用域类型。任何在花括号{ }之间的代码都属于一个代码块。代码块内的标识符可以在整个代码块内访问,但需要注意的是,若在代码块内再次声明相同名称的变量,则外层声明的变量会被隐藏。

例如:

int a;  // 文件作用域{    int b;   // 代码块作用域    a = 10;  // 隐藏了外层的a}

文件作用域

文件作用域是指标识符在整个源文件范围内都可以访问的作用域。例如,int g;int func(int x);都具有文件作用域。这也是我们在编写代码时需要将函数声明放在源文件开头的原因。

原型作用域

原型作用域仅适用于函数原型中的参数名。例如,在int func(int x);中,x的作用域仅限于函数原型本身。

函数作用域

函数作用域主要用于语句标签(用于goto语句),在实际编程中较少使用。

总的来说,代码块作用域和文件作用域是最值得关注的两种作用域类型。

二、链接属性

链接属性决定了不同源文件中相同标识符的处理方式。它与作用域密切相关,但两者性质有所不同。

external

具有外部链接属性的标识符在所有源文件中都指同一个实体。缺省情况下,文件作用域的变量和函数具有external链接属性。

internal

具有内部链接属性的标识符在同一源文件内的所有声明都指同一个实体,但在不同源文件中则视为不同的实体。

none

没有链接属性的标识符被视为独立实体,通常用于不希望标识符在其他文件中被引用。

extern关键字

extern关键字用于为标识符指定external链接属性。它对文件作用域的标识符是可选的,但对代码块作用域的标识符则强制设置为external。

static关键字

static关键字用于将外部链接属性的标识符改为内部链接属性。需要注意的是,static只对缺省链接属性为external的声明有效。

三、存储类型

存储类型决定了变量的内存分配方式和存储位置。

静态内存

静态变量在程序运行前就已经分配好内存,存储在.data段或.bss段中。静态变量在整个程序执行过程中始终存在,除非程序结束。

运行时堆栈

缺省情况下,代码块内的变量存储在运行时堆栈中,称为自动变量。若在声明时使用static关键字,则变量将被存储在静态内存中。

寄存器

寄存器变量提示编译器将变量存储在硬件寄存器中。需要注意的是,register关键字的使用更多是编译器的优化提示,实际存储位置取决于编译器的选择。

四、初始化

静态变量在编译时已经初始化为0,不需要额外开销。自动变量则需要在运行时进行初始化,编译器会在代码块开始处插入赋值语句。

五、static和extern的辨别

staticextern在不同的上下文中具有不同的含义:

1. 对于文件作用域的标识符

  • static:将外部链接属性改为内部链接属性。
  • extern:可选项,用于明确标识符的链接属性。

2. 对于代码块作用域的标识符

  • static:将变量的存储类型从自动变为静态,但链接属性仍为none。
  • extern:将变量的链接属性从none改为external。

结语

通过对作用域、链接属性和存储类型的深入理解,我们可以更好地管理代码的私有化和信息的透明化。这不仅有助于提高代码的可维护性,也能为程序的性能优化提供重要依据。在实际编程中,合理使用staticextern关键字,可以让我们的代码更高效、更易于管理。

转载地址:http://derkz.baihongyu.com/

你可能感兴趣的文章
no available service ‘default‘ found, please make sure registry config corre seata
查看>>
No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?
查看>>
no connection could be made because the target machine actively refused it.问题解决
查看>>
No Datastore Session bound to thread, and configuration does not allow creation of non-transactional
查看>>
No fallbackFactory instance of type class com.ruoyi---SpringCloud Alibaba_若依微服务框架改造---工作笔记005
查看>>
No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-loadbalanc
查看>>
No mapping found for HTTP request with URI [/...] in DispatcherServlet with name ...的解决方法
查看>>
No mapping found for HTTP request with URI [/logout.do] in DispatcherServlet with name 'springmvc'
查看>>
No module named 'crispy_forms'等使用pycharm开发
查看>>
No module named cv2
查看>>
No module named tensorboard.main在安装tensorboardX的时候遇到的问题
查看>>
No module named ‘MySQLdb‘错误解决No module named ‘MySQLdb‘错误解决
查看>>
No new migrations found. Your system is up-to-date.
查看>>
No qualifying bean of type XXX found for dependency XXX.
查看>>
No qualifying bean of type ‘com.netflix.discovery.AbstractDiscoveryClientOptionalArgs<?>‘ available
查看>>
No resource identifier found for attribute 'srcCompat' in package的解决办法
查看>>
no session found for current thread
查看>>
No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android
查看>>
NO.23 ZenTaoPHP目录结构
查看>>
no1
查看>>