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

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

相关文章

HTML5的input标签的`type`属性值详解和代码示例

《HTML5的input标签的`type`属性值详解和代码示例》HTML5的`input`标签提供了多种`type`属性值,用于创建不同类型的输入控件,满足用户输入的多样化需求,从文本输入、密码输入、... 目录一、引言二、文本类输入类型2.1 text2.2 password2.3 textarea(严格

input的accept属性让文件上传安全高效

《input的accept属性让文件上传安全高效》文章介绍了HTML的input文件上传`accept`属性在文件上传校验中的重要性和优势,通过使用`accept`属性,可以减少前端JavaScrip... 目录前言那个悄悄毁掉你上传体验的“常见写法”改变一切的 html 小特性:accept真正的魔法:让

C#借助Spire.XLS for .NET实现在Excel中添加文档属性

《C#借助Spire.XLSfor.NET实现在Excel中添加文档属性》在日常的数据处理和项目管理中,Excel文档扮演着举足轻重的角色,本文将深入探讨如何在C#中借助强大的第三方库Spire.... 目录为什么需要程序化添加Excel文档属性使用Spire.XLS for .NET库实现文档属性管理Sp

详解C++ 存储二进制数据容器的几种方法

《详解C++存储二进制数据容器的几种方法》本文主要介绍了详解C++存储二进制数据容器,包括std::vector、std::array、std::string、std::bitset和std::ve... 目录1.std::vector<uint8_t>(最常用)特点:适用场景:示例:2.std::arra

MyBatis中的两种参数传递类型详解(示例代码)

《MyBatis中的两种参数传递类型详解(示例代码)》文章介绍了MyBatis中传递多个参数的两种方式,使用Map和使用@Param注解或封装POJO,Map方式适用于动态、不固定的参数,但可读性和安... 目录✅ android方式一:使用Map<String, Object>✅ 方式二:使用@Param

C# WebAPI的几种返回类型方式

《C#WebAPI的几种返回类型方式》本文主要介绍了C#WebAPI的几种返回类型方式,包括直接返回指定类型、返回IActionResult实例和返回ActionResult,文中通过示例代码介绍的... 目录创建 Controller 和 Model 类在 Action 中返回 指定类型在 Action

python中的鸭子类型详解

《python中的鸭子类型详解》鸭子类型是Python动态类型系统的灵魂,它通过强调“行为”而非“类型”,赋予了代码极大的灵活性和表现力,本文给大家详细介绍python中的鸭子类型,感兴趣的朋友一起看... 目录1. 核心思想:什么是鸭子类型?2. 与“传统”静态类型语言的对比3. python 中无处不在

MySQL中存储过程(procedure)的使用及说明

《MySQL中存储过程(procedure)的使用及说明》存储过程是预先定义的SQL语句集合,可在数据库中重复调用,它们提供事务性、高效性和安全性,MySQL和Java中均可创建和调用存储过程,示例展... 目录概念示例1示例2总结概念存储过程:在数据库中预先定义好一组SQL语句,可以被程序反复调用。

MySQL存储过程实践(in、out、inout)

《MySQL存储过程实践(in、out、inout)》文章介绍了数据库中的存储过程,包括其定义、优缺点、性能调校与撰写,以及创建和调用方法,还详细说明了存储过程的参数类型,包括IN、OUT和INOUT... 目录简述存储过程存储过程的优缺点优点缺点存储过程的创建和调用mysql 存储过程中的关键语法案例存储

Java枚举类型深度详解

《Java枚举类型深度详解》Java的枚举类型(enum)是一种强大的工具,它不仅可以让你的代码更简洁、可读,而且通过类型安全、常量集合、方法重写和接口实现等特性,使得枚举在很多场景下都非常有用,本文... 目录前言1. enum关键字的使用:定义枚举类型什么是枚举类型?如何定义枚举类型?使用枚举类型:2.