10·C语言---存储类,作用域,生命周期,链接属性 笔记


前言

提示:只是我的笔记


一、 概念

1·1 存储类

(1)存储类就是存储类型,也就是描述C语言变量在哪种地方存储
(2)内存有多种管理方法:栈,堆,数据段,bss段, 代码段(.tset段)…
一个变量的存储类属性就是描述这个变量存储在哪种内存段中。
(3)譬如:局部变量分配在栈上,所以他的存储类型就是栈;显式初始化为非0的全局变量分配在数据段,显式初始化0和没有显式初始化的全局变量分配在bss段。

1·2 作用域

(1)描述变量起作用的代码范围

1·3 生命周期

(1)生命周期描述的是变量生命时候诞生(运行时分配内存空间给这个变量)以及什么时候死亡(运行时收回这个内存空间,此后不能访问这个内存地址,或者访问这个内存地址已经和这个变量无关了)。

1·4 链接属性

(1)源代码到可执行程序需要经历:编译,链接。
(2)编译:把源代码变成 .o目标文件,目标文件里面有很多符号和代码段,数据段,bss段等分段。符号就是编程中的变量名,函数名等。运行时变量名,函数名能够和相应的内存对应起来,靠符号来做链接。
(3).o 目标文件链接生成最终可执行程序的时候,其实是把符号和对应的段给链接起来。C语言的符号有三种链接属性:外链接属性,内链接属性,无链接属性。

二、 Linux下c程序的内存映像

在这里插入图片描述

2·1 代码段,只读数据段

(1)代码段与只读数据段对应程序中的代码(函数),代码段在Linux中又叫文本段(.text)
(2)只读数据段存放是程序在运行期间只能读不能写的数据,const修饰的常量有可能存在只读数据段(但是不是绝对的,因为平台不同const常量的实现方法是不一样的)

2·2 数据段、bss段

(1)数据段:存放显式初始化非0的全局变量,显式初始化非0的static局部变量

(2)bss段:存放显式初始化为0或者未显式初始化的全局变量;显式初始化为0或者未显式初始化的static全局变量。

2·3 堆

malloc 与 free

2·4 文件映射区

(1)文件映射区就是进程打开了文件后,将这个文件的内容从硬盘得到进程的文件映射区,以后就直接在内存中操作这个文件,读写完了后保存时再将内存中的为文件写到硬盘中去。

2·5 栈

(1)局部变量分配在栈内存上;函数调用传参过程也会用到栈

2·7 内核映射区

(1)内核映射区就是将操作系统内核程序映射到这个区域了。
(2)对于Linux中的每一个进程来说,它都以为整个系统中只有它自己和内核而已。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、 存储类相关的关键字

3·1 auto

(1)只有一个作用:修饰局部变量。
(2)auto修饰局部变量表示整个局部变量是一个自动局部变量,自动局部变量分配在栈上。既然分配在栈上,那就说明它如果不初始化那么值就是随机的
(3)平时定义局部变量就是定义的auto的,只是省略 关键字而已。可见,auto的局部变量其实就是默认的定义的普通的局部变量。

3·2 static

static有两种用法,并且两种用法独立,完全不同。

(1)static的第一种用法:修饰局部变量,形成静态局部变量。
静态局部变量 于 非静态局部变量的区别:存储类型的不同
在这里插入图片描述
在这里插入图片描述

(2)static的第二种用法:修饰全局变量和函数
普通的(非静态的)全局变量 / 函数,默认是外部链接属性。
static(静态的)全局变量 / 函数,是内部链接属性。
在这里插入图片描述
**static使全局变量 / 函数的链接属性由外部(整个程序所有文件范围)转为内部链接(当前c文件内)。**这是为了解决全局变量 / 函数的重名问题。

3·3 register

(1)整个关键字不常用,也只有一个作用,那就是:register修饰的变量(一般是全局变量)编译器会尽量将它分配在寄存器中。(平时分配的一般变量都是在内存中的)。分配在寄存器中的变量的读写效率会高很多。所以register修饰的变量用在那种变量被反复高频率的使用,通过改善整个变量的访问效率可以极大的提升程序运行效率。
在这里插入图片描述
(2)平时写代码要慎用
(3)register编译器只能尽量将register修饰的变量放在寄存器中,但是不保证一定会放在寄存器中。原因是,寄存器的数量有限。

3·4 exter

(1)主要用来修饰全局变量,exter修饰的全局变量可以在不同的文件之间被引用,但是不能被初始化。

3·5 volatile

在这里插入图片描述
在这里插入图片描述

3·6 restrict

在这里插入图片描述

四、 作用域详解

(1)局部变量的代码块作用域
(2)函数名和全局变量的文件作用域
(3)同名变量的掩蔽规则
在这里插入图片描述

五、 变量的生命周期

(1)栈变量的生命周期
局部变量(栈变量)存储在栈上,生命周期是临时的。临时:代码段的创建,使用,消亡。

函数内部的一个局部变量,在整个函数每一次被调用时都会创建一次,然后使用,最后在函数返回时消亡。

(2)堆变量的生命周期
从malloc到free之间

(3)数据段,bss段变量的生命周期
全局变量存储于数据段,bss段。全局变量的生命周期是永久的,永久:在程序被执行时诞生,在程序终止时消亡。
全局变量所占内存是不能被程序自己释放的,因此程序如果申请过多的全局变量会导致程序一直占用大量内存。

(4)代码段,只读段的生命周期
程序执行的代码其实就是函数,代码段,只读段的的生命周期是永久的:程序执行时诞生,程序终止时消亡。

六、 链接属性

6·1 C语言程序的组织架构:多个c文件+多个h为文件
程序的生成过程就是:编译+链接
编译:将函数或者变量变成 .o 二进制的机器码格式,链接:将各个独立分开的二进制函数链接起来形成一个整体的二进制可执行程序。

6·2 编译以文件为单位,链接以工程为单位

6·3 三种链接属性:外链接,内链接,无链接
(1)外链接:外部链接属性,也就是说外链接可以在整个程序范围内(也就是说可以跨文件)进行链接。

普通的函数和全局变量属于外链接。

(2)内链接:内部链接属性,也就是说可以在当前c文件内部范围内进行链接(也就是说只能在当前c文件,不能再其他c文件中进行访问,链接)

static修饰的函数/全局变量 属于内链接。

(3)无链接:符号本身不参与链接,它和链接没关系。所有的局部变量(auto的,static的局部变量)都是无连接的

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值