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

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

相关文章

SpringBoot3.X 整合 MinIO 存储原生方案

《SpringBoot3.X整合MinIO存储原生方案》本文详细介绍了SpringBoot3.X整合MinIO的原生方案,从环境搭建到核心功能实现,涵盖了文件上传、下载、删除等常用操作,并补充了... 目录SpringBoot3.X整合MinIO存储原生方案:从环境搭建到实战开发一、前言:为什么选择MinI

Linux线程之线程的创建、属性、回收、退出、取消方式

《Linux线程之线程的创建、属性、回收、退出、取消方式》文章总结了线程管理核心知识:线程号唯一、创建方式、属性设置(如分离状态与栈大小)、回收机制(join/detach)、退出方法(返回/pthr... 目录1. 线程号2. 线程的创建3. 线程属性4. 线程的回收5. 线程的退出6. 线程的取消7.

Python函数作用域示例详解

《Python函数作用域示例详解》本文介绍了Python中的LEGB作用域规则,详细解析了变量查找的四个层级,通过具体代码示例,展示了各层级的变量访问规则和特性,对python函数作用域相关知识感兴趣... 目录一、LEGB 规则二、作用域实例2.1 局部作用域(Local)2.2 闭包作用域(Enclos

Python实现对阿里云OSS对象存储的操作详解

《Python实现对阿里云OSS对象存储的操作详解》这篇文章主要为大家详细介绍了Python实现对阿里云OSS对象存储的操作相关知识,包括连接,上传,下载,列举等功能,感兴趣的小伙伴可以了解下... 目录一、直接使用代码二、详细使用1. 环境准备2. 初始化配置3. bucket配置创建4. 文件上传到os

Java中调用数据库存储过程的示例代码

《Java中调用数据库存储过程的示例代码》本文介绍Java通过JDBC调用数据库存储过程的方法,涵盖参数类型、执行步骤及数据库差异,需注意异常处理与资源管理,以优化性能并实现复杂业务逻辑,感兴趣的朋友... 目录一、存储过程概述二、Java调用存储过程的基本javascript步骤三、Java调用存储过程示

python删除xml中的w:ascii属性的步骤

《python删除xml中的w:ascii属性的步骤》使用xml.etree.ElementTree删除WordXML中w:ascii属性,需注册命名空间并定位rFonts元素,通过del操作删除属... 可以使用python的XML.etree.ElementTree模块通过以下步骤删除XML中的w:as

MySQL之InnoDB存储引擎中的索引用法及说明

《MySQL之InnoDB存储引擎中的索引用法及说明》:本文主要介绍MySQL之InnoDB存储引擎中的索引用法及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录1、背景2、准备3、正篇【1】存储用户记录的数据页【2】存储目录项记录的数据页【3】聚簇索引【4】二

MySQL之InnoDB存储页的独立表空间解读

《MySQL之InnoDB存储页的独立表空间解读》:本文主要介绍MySQL之InnoDB存储页的独立表空间,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、独立表空间【1】表空间大小【2】区【3】组【4】段【5】区的类型【6】XDES Entry区结构【

SQLite3 在嵌入式C环境中存储音频/视频文件的最优方案

《SQLite3在嵌入式C环境中存储音频/视频文件的最优方案》本文探讨了SQLite3在嵌入式C环境中存储音视频文件的优化方案,推荐采用文件路径存储结合元数据管理,兼顾效率与资源限制,小文件可使用B... 目录SQLite3 在嵌入式C环境中存储音频/视频文件的专业方案一、存储策略选择1. 直接存储 vs

C++11作用域枚举(Scoped Enums)的实现示例

《C++11作用域枚举(ScopedEnums)的实现示例》枚举类型是一种非常实用的工具,C++11标准引入了作用域枚举,也称为强类型枚举,本文主要介绍了C++11作用域枚举(ScopedEnums... 目录一、引言二、传统枚举类型的局限性2.1 命名空间污染2.2 整型提升问题2.3 类型转换问题三、C