C语言:链接属性与存储类型

一、 链接属性

C语言中链接属性决定如何处理在不同文件中出现的标示符。标示符的作用域与它的链接属性有关,但这两个属性并不相同。

链接属性有3种: external(外部),internal(内部) 和 none(无)。

1. none: 没有链接的标示符,总是被当做单独的个体,也就是说改标示符的多个声明被当做不同的实体。

2. internal: 在同一个源文件内的所有声明中都指同一个实体,但位于不同源文件的多个声明则分属不同的实体。

3. external: 标示符不论声明多少次,位于几个文件都表示同一个实体。

举一个简单的例子对链接属性进行说明,如下图:

1. 在缺省情况下,标示符b,c,f 的链接属性为external, 其余标示符的链接属性则为none。因此,另一个源文件也包含了标示符b的类似声明并调用函数c,他们实际上访问的是这个源文件所定义的实体。f的链接属性之所以是external,是因为它是函数名。这个源文件中调用f,实际上将链接到其他源文件所定义的函数,甚至这个函数的定义可能出现在某个函数库。

2. 关键字extern和static用于在声明中修改标示符的连接属性。如果某个声明在正常情况下具有external链接属性,在它前面加上static关键字可以使它的链接属性变为internal。例如,将b声明为

static int b;

那么变量b就将为这个源文件所私有。在其他源文件中,如果也链接到一个叫做b的变量,那么它所引用的是另一个不同的变量。

3. static只对缺省链接属性为external的声明才有改变链接属性的效果。例如,你尽管可以在变量e前面加上static关键字,但它的效果完全不一样,因为e的缺省链接属性不是external。

二、 存储类型

变量的存储类型是指存储变量值的内存类型。有三个地方可以用于存储变量:普通内存、运行时堆栈、硬件寄存器。变量的缺省存储类型取决于它的声明位置。

1. 凡是在任何代码块之外声明的变量总是存储于静态内存中,也就是不属于堆栈的内存,这类变量称为静态(static)变量。静态变量在程序运行之前创建,更确切的说,是在将可执行文件加载到内存的时候创建,其在程序的整个执行期间始终存在。

2. 在代码块内部声明的变量的缺省存储类型是自动的(automatic), 也就是说它存储于堆栈中,称为自动变量。有一个关键字auto就是用于修饰这种存储类型的,但它极少使用,因为代码块中的变量缺省情况下就是自动变量。在程序执行到声明自动变量的代码块时,自动变量才被创建,当程序的执行流离开代码块时,这些自动变量便自行销毁。在代码块内部声明的变量,如果给它加上static,可以使它的存储类型从自动变为静态。注意,修改变量的存储类型并不表示修改改变量的作用域。它任然只能在该代码块内部按名字访问。函数的形式参数不能声明为静态,因为实参总是在堆栈中传递给函数。

3. 关键字register可以用于自动变量的声明,提示它们应该存储于机器的硬件寄存器而不是内存中。

三、 static关键字使用说明

注意到在“连接属性”和“存储类型”中都有可能使用到static关键字,因为我们有必要搞清楚在不同情况下,static关键字的作用。

1. 当它作用于函数定义时,或者用于代码块之外的变量声明时,static关键字用于修改标示符的链接属性。

从external改为internal,但标示符的存储类型和作用域不受影响。用这种方式声明的函数或变量只能在声明它们的源文件中访问。

2. 当它作用于代码块内部的变量声明时,static用于修改变量的存储类型。

从自动变量修改为静态变量,但变量的链接属性和作用域不受影响。用这种方式声明的变量在程序执行之前创建,并在程序的整个执行期间一直存在。

四、 作用域、存储类型示例

我们就以下面的示例代码进行说明。

1. 第1行a的链接属性为external,第二行extern在技术上并非必要,第三行的static关键字修改了c的缺省链接属性,把它改为internal。声明了变量a和b(具有external链接属性)的其他源文件在使用这两个变量时实际所访问的是声明与此处的这两个变量。但变量c只能由这个源文件访问,因为它具有internal链接属性。

2. 变量a,b,c 的存储类型为静态,表示它们并不存储于堆栈中。因此,这些变量在程序执行之前创建,并一直保持它们的值,直到程序结束。

3. 第4行声明了两个标示符,d的作用域从第四行直到文件结束。对于函数而言,存储类型不是问题,因为代码总是存储在静态内存中的。参数e不具有链接属性,所以我们只能从函数内部通过名字访问它。

4. 第6~8行声明局部变量,所以它们的作用域到函数结束为止,它们不具有链接属性,所以它们不能在函数的外部通过名字访问。变量g的存储类型是静态,所以它在程序的整个执行过程中一直存在。当程序开始执行时,它被初始化为20。当函数每次被调用时,它并不会被重新初始化。

5. 第9行的声明并不需要,这个代码位于第1行声明的作用域之内。

6. 第12,13行代码块声明为局部变量。它们都具有自动存储类型,不具有链接属性。

7. 第14行使全局变量h在这个代码块内可以被访问。它具有external链接属性,存储于静态内存中。

8. 第19,20行用于创建局部变量。

9. 第25行声明了函数i,它具有静态链接属性。

五、 作用域、链接属性和存储类型总结

六、 变量存储区域分配图

大家可以根据上述示例代码,将变量一一对应的放到指定的区域。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-13 00:54:36

C语言:链接属性与存储类型的相关文章

C语言中的作用域,链接属性和存储类型

作用域 当变量在程序的某个部分被声明的时候,他只有在程序的一定渔区才能被访问,编译器可以确认4种不同类型的作用域:文件作用域,函数作用域,代码块作用域和原型作用域 1.代码块作用域:位于一对花括号之间的所有语句称为一个代码块.任何在代码块的开始位置声明的标识符都具有代码块作用域,表示他可以被这个代码块中的所有语句访问.(例子中:f,g函数,i) 2.文件作用域:任何在所有代码块之外声明的标识符都具有文件作用域,他表示这些标识符从他们的声明之处直到他所在的源文件结尾处都是可以访问的.(例子中:a,

【转】作用域、链接属性、存储类型总结--转载学习,很清晰,很详细

标识符: 首先,在讨论这三种东西之前,详细说明一下C语言中的标识符. 标识符是用户编程为变量.常量.函数.语句等指定的名字,就好比人名一样的东西. 标识符的命名规则如下: 1.只能由字母.数字.下划线组成,并且首字符不能是数字: 2.不能把C语言的关键字作为标识符: 3.对大小写敏感: 其次,需要明确,作用域和链接属性是在标识符范畴内讨论的,存储类型是在标识符中的变量范畴内讨论的. 作用域: 标识符的作用域就是程序中该标识符可以被使用的区域,由它的声明位置决定. 分为以下四类: 1.文件作用域

关于extern和static关键字引出的一些关于作用域和链接属性和存储类型的问题

在进入正题前我们必须了解一些概念: 标识符:标识符不仅仅代表着变量的名字,main()函数的main也是一个标识符,这点很重要. 存储类型:即变量的存储位置及其生存周期:静态区:分为两块 .date 已显式初始化的全局变量了静态变量 .bss 存放未初始化的全局或者静态变量 注意:静态变量的初值是在编译时就进行初始化了:意思就是用static修饰的变量赋过数值的话就保存为他的初值,如果没有初始化的话就赋值为零,且整个程序只初始化一次:即不管static int i = 1:或者这 static

嵌入式 Linux C语言(八)——存储类型、作用域、生命周期、链接属性

嵌入式 Linux C语言(八)--存储类型.作用域.生命周期.链接属性 一.存储类型 C语言中,每个变量和函数都有两个属性:数据类型和数据的存储类型. 变量的存储类型是指存储变量值的内存类型.变量的存储类型决定变量何时创建.何时销毁以及它的值将保持多久.计算机中有三个地方可以用于存储变量:普通内存,运行时堆和栈,硬件寄存器.变量的存储类型取决于声明变量的位置. C语言存储类别说明符: 说明符 用    法 auto 只在代码块内变量声明中被允许, 表示变量具有本地生存期 extern 出现在顶

C语言中变量的存储类型

在C语言中,对变量的存储类型说明有以下四种: auto 自动变量register   寄存器变量extern 外部变量static   静态变量 自动变量和寄存器变量属于动态存储方式,外部变量和静态变量属于静态存储方式. 在介绍了变量的存储类型之后,可以知道对一个变量的说明不仅应说明其数据类型,还应说明其存储类型. 因此变量说明的完整形式应为:存储类型说明符数据类型说明符变量名,变量名-:例如: static int a,b;      说明a,b为静态类型变量 auto char c1,c2;

作用域、全局局部变量、链接属性、存储属性、生存期、内部外部函数

1. 首先看函数的定义: 类型 函数名(形式参数) { 代码块 //函数体就是代码块 } 函数名本身不属于任何代码块. 函数原型中声明参数 // 原型作用域.在原型中,参数的名字并非必须.如果出现,可以随便取任何名字,不必和形参.实参匹配. 函数定义的形式参数 //在函数体内部具有代码块作用域 函数调用的实际参数 2. 作用域(是对标识符而言,标识符:就是变量.函数.类型等的名字.它们有大小写字母.数字和下划线组成,但不能以数字开头.) 代码块作用域:任何在代码块的开始位置声明的标识符都具有代码

C和指针 3.9作用域、存储类型示例

1 int a = 5; 2 extern int b; 3 static int c; 4 5 int d( int e ) 6 { 7 int f = 15; 8 register int b; 9 static int g = 20; 10 extern int a; 11 ... 12 { 13 int e; 14 int a; 15 extern int h; 16 ... 17 } 18 ... 19 { 20 int x; 21 int e; 22 ... 23 } 24 ...

C语言中变量存储类型有哪些?

变量的存储类型是C语言的重要组成部分,也是C语言学习的基础.那C语言中变量的存储类型有哪几种呢?在编程过程中又该怎样运用呢?就这一问题,我今天给大家介绍一下!总的来说,C语言中变量的存储类型可以分为四种,他们分别是自动变量.静态变量.外部变量和寄存器变量这四种,他们的说明符依次是:auto.static.extern和register. 一.auto auto称为自动变量. 局部变量是指在函数内部说明的变量(有时也称为自动变量).用关键字auto进行说明,当auto省略时,所有的非全程变量都被认

Swift研究之编程高级教程(二)属性,存储属性详解

 属性 属性是依赖于某个特定的类.结构体或者枚举类型的值.Swift有两种属性:存储类型和计算类型.其中存储类型可以作为实例的一部分存放变量或者常量的值,而计算类型的属性值是通过运算的来的.计算类型的属性可以在类.结构体和枚举类型中出现,但存储类型只可能出现在类和结构体类型中. 属性一般依赖于一个特定类型的实例,但是也可以依赖于类本身.依赖于类型本身的属性称为类型属性. 可以定义属性观察者来监督属性值的改变,从而作出响应.对集合不明白的看集合类型-数组详解 存储属性 常量属性let的值在初始