【C语言之存储类 作用域 生命周期 链接重要知识点】

C语言之存储类 作用域 生命周期 链接

c语言浅学了一段时间了,定义不同的变量是如何在我们内存上分配的,他们各自的作用域以及生命周期等又是如何呢?下面就简单的分享一下。

一、存储类

内存的管理方式总的来说有以下几种:
栈、堆、数据段、bss段、text段
譬如:函数的局部变量分配在栈上,所以它的存储在栈上;显示初始化为非0的全局变量分配在数据段,显示初始化为0或为初始化的全局变量分配在bss段,这也是为什么一般我们在定义局部变量的时候需要初始化要不然,它的值就可能是一个随机的值,而定义全局变量的时候可以不初始化也是0(这都取决于他们分配时所在的内存区间)下面会具体说明。

二、作用域(描述变量所起作用的范围)

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

从上面结果我们可以得出简单结论:变量所在的作用域在{}之间起作用,如果定义的是全局变量则所在作用域为这个程序运行结束。上面例子中定义的a在for循环{}所在范围内起作用所以下面跳出{}后所打印a时就会报错,未定义该变量

三、生命周期

生命周期就是描述一个变量什么时候诞生什么时候结束。研究变量的生命周期可以帮助我们理解一些现象属性。(作用域与变量的存储类息息相关)

 四、链接属性

1、程序从源程序到可执行程序经历过程:编译、链接
2、编译阶段就是把.c文件搞成.o文件
3、c语言中有三种链接属性:外连接属性、内连接属性、无连接属性
(存储类与链接属性息息相关)

五、linux下c程序的内存映象

一、代码段、只读数据段
1.代码段在linux中又讲文本段(.text)
2.只读数据段就是在程序运行时只能读不能写的数据const修饰的常量就是存储在只读数据段。
二、数据段、Bss段
1.数据段:显示初始化为非零的全局变量和显示初始化为非零的static修饰的局部变量。
2.bss段:显示初始化为零的和未初始化的全局变量
三、堆
程序员根据自己的需求手动申请空间 malloc (申请 ) free(释放)
堆的特点
1.使用更加灵活通过程序员自己的需求进行申请和释放
2.使用时要更加注意一些小细节(使用完要及时进行释放)
3.反复使用(进行空间申请的时候也是在一块特点的内存区域进行不断的申请和释放)
四、栈
局部变量分配在栈上,函数调用传参也会用到栈
栈的特点
1.由系统自动进行内存空间的分配和销毁
2.使用不灵活,不能根据自己的需求进行内存空间合理的分配
3.脏内存(因为栈的大小也是有限的进行栈上内存空间分配时也是不断的在同一块栈空间进行使用)
4.反复使用
5.注意栈溢出等问题(定义变量过大、不断递归调用)
五、内核映射区
1.将操作系统的内核程序映射到这个区域
2.对于linux中的每一个进程来说,它都以为整个系统只有他自己和内核
3.每一个进程都活在自己独立的空间,0-3G空间每一个进程都是不同的(因为在内核中使用的是虚拟内存地址技术),但是内核是唯一的
六、Os下和裸机下c程序的区别
1.这段协助代码叫做加载运行代码,作用是:给全局变量赋值、清bss段(c语言中为初始化的全局变量为0的原因正是因为这个)
2.数据段的全局变量和静态局部变量都是非0的初始化,这些处置在main函数之前就已经初始化了,是重定位期间完成的初始化。

六、存储类相关的关键字

一、auto关键字作用只有一个就是用来修饰局部变量
1、auto关键字修饰局部变量说明了这个局部变量是自动局部变量,自动局部变量分配在栈上,所以如果不初始化它的值时随机的
2、我们在平时定义局部变量的时候就是定义的auto类型的,只是省了auto关键字,可见auto的局部变量就是默认定义普通的局部变量
二、static关键字
总的来说static在c语言中只有两种不同的用法
1、第一种用法:用来修饰局部变量,形参静态局部变量,静态和非静态的局部变量主要区别在于存储类不同,静态局部变量是分配在数据段或bss段的,而普通的局部变量是分配在栈上的。
2、第二种用法:用来修饰全局变量,形成静态全局变量,静态和非静态(也就是普通的全局变量的区别主要在于)他们的链接属性不同(下面会具体讲解什么是具体的链接属性)。
分析:
1)静态局部变量的存储类和全局变量是一样的
2)静态局部变量的生命周期和全局变量一样
3)静态局部变量和全局变量的区别在于:作用域、链接属性。静态局部变量的作用域(和普通局部变量是一样的)、链接属性是五链接的;全局变量的作用域是文件作用域(和函数是一样的)也就是整个程序。
三、extern关键字
声明全局变量、用extern声明的变量可以在不同的c文件之间进行使用,如果不用extern声明则会报错

demo1.c

在这里插入图片描述

demo2.c

在这里插入图片描述
运行结果
在这里插入图片描述

从上面结果分析我们在主函数中使用的val变量由于在另一个文件定义时未用extern进行声明所以找不到编译时会报错。
五、register关键字
register关键字的作用只有一个就是用该关键字所修饰的变量会分配在寄存器中(大大提高效率)
六、volatile关键字
1、volatile关键字:可变的、易改变的该关键字修饰的变量,编译器在遇到volatile修饰的变量时不会对该变量进行优化,就不会出现错误
2、volatile来修饰时,当程序继续进行则该值就不会改变,因此我们也得不到我们想要的值。所以我们在(中断ISR中引用变量、多线程中的共用变量、硬件会更改的变量)情况下我们最好用volatile来修饰该变量
七、restrict关键字
只是用来修饰指针,不能修饰普通变量

七、链接属性

链接属性可以分为:外链接、内链接、无链接三种方式
1、普通函数和全局变量属于外链接(可以跨文件进行链接)
2、内链接的意思就是内部属性,只能在一个c文件内部范围内进行链接,不能再c文件以外的地方进行链接(static修饰的函数、全局变量)属于内链接
3、无链接的意思就是这个符号不参与链接,所有局部变量(auto,static)都是属于无链接

以上就是C语言中存储类、作用域、生命周期和链接属性相关的知识点了。
熟练的掌握该知识点可以更好的帮助我们对变量的理解,分配方式,存储地方,作用范围,生命周期以及链接属性

猜你喜欢

转载自blog.csdn.net/boybs/article/details/122977704