作用域+链接属性+存储类型

2024-09-02 17:38

本文主要是介绍作用域+链接属性+存储类型,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.作用域

     当变量在程序的某一部分被声明时,只有在程序的一定区域才能被访问。这个区域由标示符的作用域(scope)决定。换句话说,标示符的作用域,就是该标示符在程序中能被使用的区域。
    编译器可以确认4种不同类型的作用域:文件作用域、函数、代码块、原型作用域。

代码块作用域:(block scope)用{。。。。。}括起来的部分
文件作用域:任何在代码块外部声明的标示符都具有文件作用域。
原型作用域:(prototype scope)只适用于在函数原型中声明的参数名
函数作用域:只适用于语句标签,语句标签用于goto语句。一个函数中的所有语句标签必须唯一

2.链接属性

    各个源文件被编译后,所有的目标文件+从函数库中引用的函数(一般是归档库文件,*.a类型)经过链接器链接,形成一定格式的可执行程序,如elf格式。
    如果相同的标示符出现在几个不同个源文件中,他们是否表示同一个实体。这由标示符的链接属(linkage)决定。标示符的作用域和链接属性相关,作用域是由链接属性决定的,但二者并不相同。
比如,内部属性的静态全局变量,在代码块内有同样名称的标示符,这时静态变量无效,起作用的是代码块内的局部变量。虽然静态全局变量具有内部链接属性,但当名字冲突时,起作用的是局部变量。

链接属性:外部(external),内部(internal),无(none)。
分别说明:
外部属性的标示符在整个程序内,不论出现于哪个文件,不论声明多少次,都指的同一个实体。
内部属性,只在同一个源文件的所有声明中指同一个实体。
无属性,该标示符的多个声明都被当做独立的个体。

这里有两个关键字:extern  和  static,用于在声明中修改标示符的链接属性。
如果某个声明默认情况下具有外部external属性,加上static后,可以将其链接属性变为internal、。
static可以将该标示符的作用域限定为本文件,防止被其他源文件使用。
注:static只对缺省链接属性为external的声明才有改变链接属性的效果。

extern关键字可以声明一个变量,告诉要使用它的文件或函数,这个变量在别的文件内声明,这里只是引用。所以,extern扩大了一个标示符的作用域。

3.存储类型

变量的存储类型(storage class)是指存储变量值的内存类型。变量的存储类型决定了变量何时创建,何时销毁以及它的值保持多久。
有三个地方可以用于存储变量:普通内存,运行时堆栈,硬件寄存器。

变量的存储类型取决与它的声明位置。

(1)在任何代码块之外声明的变量总是存储于静态内存(程序的数据段+bss段BSS(Block Started by Symbol)通常是指用来存放程序中未初始化的全局变量和静态变量的一块内存区域。 注意和数据段的区别,BSS存放的是未初始化的全局变量和静态变量,数据段存放的是初始化后的全局变量和静态变量),而不是堆栈中,这类变量是静态变量(或全局变量)。
静态变量在程序运行之前创建,在程序的整个执行过程中都存在。

(2)在代码块内声明的变量默认是自动变量(automatic),存储于堆栈中,这类变量叫做自动(auto)变量。在程序执行到该代码块时,内部的自动变量才被创建,当程序离开该代码块时,自动变量销毁。

在代码块内部的变量如果给它加上static关键字,可以使其变为静态变量。
注:1.修改变量的存储类型,不等于修改变量的作用域,它仍然只能在该代码块内部按名字访问。
    2.函数的形式参数不能声明为静态,因为函数的参数传递是通过堆栈进行的,用于支持递归。

(3)在变量前加上register关键字,可以告诉编译器该变量应该存储于机器的硬件寄存器,而不是内存。如果有很多register变量,编译器只会选几个实际存储于寄存器。


4.变量的初始化

静态变量总是默认初始化为0,除非显式的赋值。
自动变量没有初始值,或认为它的值是个垃圾,所以在声明一个自动变量时最好在使用前进行赋初值。。

PS:自动变量+非自动变量,非自动变量(静态变量+全局变量)
PS:volatile  易失变量(嵌入式编程经常要用到这个变量)
(1)表示变量是易失的,易变的. (2)强制访存操作,防止编译器去优化,告诉编译器每次必须去内存中取值,而不是从寄存器或者缓存.
 
 
《C和指针(中文版)》上一道题,P49:
假如想着同一个源文件里写两个函数x,y,需要满足以下条件:
名字        类型       存储类型        链接类型       作用域                                  初始值
a              int              static            external          x可以访问,y不能              1
b              char           static            none               x,y都可以访问                     2
c              int              automatic     none              x的局部变量                         3
d              float           static            none              x的局部变量                         4
 
a链接属性external,应该位于所有代码块外面,但由于x可以访问,y不能,所以要出现在y函数后面,x函数前面;
b链接类型为none,则应该位于代码块内,具有代码块作用域。但是由于x,y都能访问到,所以x需要调用y,或反之。。(笔者以为,b的链接类型应该是internal,且位于文件起始处)
c,d明显要处于x的代码块内,且一个为static变量,一个automatic变量。
 
形式如下:
    static int b = 2;void y(){...}int a =1;void x(){int c = 3;static d = 4;....}


zuo

这篇关于作用域+链接属性+存储类型的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1130627

相关文章

CSS3中的字体及相关属性详解

《CSS3中的字体及相关属性详解》:本文主要介绍了CSS3中的字体及相关属性,详细内容请阅读本文,希望能对你有所帮助... 字体网页字体的三个来源:用户机器上安装的字体,放心使用。保存在第三方网站上的字体,例如Typekit和Google,可以link标签链接到你的页面上。保存在你自己Web服务器上的字

MySQL存储过程之循环遍历查询的结果集详解

《MySQL存储过程之循环遍历查询的结果集详解》:本文主要介绍MySQL存储过程之循环遍历查询的结果集,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言1. 表结构2. 存储过程3. 关于存储过程的SQL补充总结前言近来碰到这样一个问题:在生产上导入的数据发现

一文全面详解Python变量作用域

《一文全面详解Python变量作用域》变量作用域是Python中非常重要的概念,它决定了在哪里可以访问变量,下面我将用通俗易懂的方式,结合代码示例和图表,带你全面了解Python变量作用域,需要的朋友... 目录一、什么是变量作用域?二、python的四种作用域作用域查找顺序图示三、各作用域详解1. 局部作

C++作用域和标识符查找规则详解

《C++作用域和标识符查找规则详解》在C++中,作用域(Scope)和标识符查找(IdentifierLookup)是理解代码行为的重要概念,本文将详细介绍这些规则,并通过实例来说明它们的工作原理,需... 目录作用域标识符查找规则1. 普通查找(Ordinary Lookup)2. 限定查找(Qualif

SpringBoot读取ZooKeeper(ZK)属性的方法实现

《SpringBoot读取ZooKeeper(ZK)属性的方法实现》本文主要介绍了SpringBoot读取ZooKeeper(ZK)属性的方法实现,强调使用@ConfigurationProperti... 目录1. 在配置文件中定义 ZK 属性application.propertiesapplicati

Java反射实现多属性去重与分组功能

《Java反射实现多属性去重与分组功能》在Java开发中,​​List是一种非常常用的数据结构,通常我们会遇到这样的问题:如何处理​​List​​​中的相同字段?无论是去重还是分组,合理的操作可以提高... 目录一、开发环境与基础组件准备1.环境配置:2. 代码结构说明:二、基础反射工具:BeanUtils

MySQL 存储引擎 MyISAM详解(最新推荐)

《MySQL存储引擎MyISAM详解(最新推荐)》使用MyISAM存储引擎的表占用空间很小,但是由于使用表级锁定,所以限制了读/写操作的性能,通常用于中小型的Web应用和数据仓库配置中的只读或主要... 目录mysql 5.5 之前默认的存储引擎️‍一、MyISAM 存储引擎的特性️‍二、MyISAM 的主

Linux lvm实例之如何创建一个专用于MySQL数据存储的LVM卷组

《Linuxlvm实例之如何创建一个专用于MySQL数据存储的LVM卷组》:本文主要介绍使用Linux创建一个专用于MySQL数据存储的LVM卷组的实例,具有很好的参考价值,希望对大家有所帮助,... 目录在Centos 7上创建卷China编程组并配置mysql数据目录1. 检查现有磁盘2. 创建物理卷3. 创

MySQL 事务的概念及ACID属性和使用详解

《MySQL事务的概念及ACID属性和使用详解》MySQL通过多线程实现存储工作,因此在并发访问场景中,事务确保了数据操作的一致性和可靠性,下面通过本文给大家介绍MySQL事务的概念及ACID属性和... 目录一、什么是事务二、事务的属性及使用2.1 事务的 ACID 属性2.2 为什么存在事务2.3 事务

使用Python实现调用API获取图片存储到本地的方法

《使用Python实现调用API获取图片存储到本地的方法》开发一个自动化工具,用于从JSON数据源中提取图像ID,通过调用指定API获取未经压缩的原始图像文件,并确保下载结果与Postman等工具直接... 目录使用python实现调用API获取图片存储到本地1、项目概述2、核心功能3、环境准备4、代码实现