9 存储类、作用域、生命周期、链接属性

Linuxc下C程序的内存映像

在这里插入图片描述

代码段、rodata段(只读数据段)

对应程序中的代码(函数)、代码段在Linux中又叫文本段(.text);
rodata段常常用于存储常量数据,也被称为只读段,比如修饰的常量有可能存储在rodata段中。

数据段、bss段

data段:存放被初始化为非0的全局变量;被初始化为非0 的static局部变量;
bss段:存放未初始化的全局变量;未初始化的static修饰的局部变量。

堆的操作由程序员手工完成,使用malloc申请空间,使用完成后用free释放空间,否则会造成内存泄漏。

文件映射区

文件映射区是进程打开文件后,将文件的内容从硬盘读到进程的文件映射区,以后直接在内存中操作这个文件,读写完成后保存时,再将内存中的文件写道硬盘中。

栈内存区,局部变量分配在栈上,函数传参也会用到栈。

内核映射区

内核映射区就是将操作系统内核程序映射到这个区域。

1 存储类

存储类就是存储类型。变量空间开辟于内存之中,存储类就是用于描述变量空间开辟内存中什么地方。事实上内存被分为栈、对、数据段、bss段和text段等不同管理方法的内存段。

存储类相关的关键字

(1)auto
auto修饰局部变量,表示这个局部变量是自动局部变量,自动局部变量分配在栈上。
(2)static
用法一:
用来修饰局部变量,形成静态局部变量。静态局部变量和自动局部变量的本质区别是存储类不同,自动局部变量分配在栈上,而静态局部变量是分配在data段或者bss段上的。
用法二:
用来修饰全局变量,形成静态全局变量。当static修饰函数和全局变量时,函数和全局变量的作用范围被锁在本文件中,其他文件在链接时无法使用这些函数和全局变量,这就是内链接。
静态局部变量和全局变量的异同点
1)静态局部变量在存储类方面(数据段)和全局变量一样;
2)静态局部变量在生命周期方面和全局变量一样;
3)静态局部变量的作用域是代码块作用域(和自动局部变量一样),连接属性是无连接的;全局变量作用域是文件作用域(和函数一样的),链接属性是外连接
(3)register
使用register关键字修饰变量时,编译器会尽量将它分配在寄存器中,平时变量空间都是分配在内存中,register修饰的被称为寄存器变量,寄存器变量的读写效率高。
(4)extern
extern修饰全局变量,可以跨文件访问变量。
声明和定义的区别
定义是编译器创建了具体的变量,并且为这个变量分配内存;声明并没有分配内存,只是告诉编译器这个名字已经被分配内存了,不能在分配内存了。
(5)volatile
volatile修饰变量时,表示被编译器之外的东西改变,防止编译器进行优化。编译器之内表示变量值的改变是代码作用的结果,编译器之外的改变不是由代码造成的或者不是由当前代码造成的,编译器在编译当前代码时无法预知。
中断isr中引用的变量;多线程中共用的变量;硬件会更改的变量都是编译器在编译时无法预知的,使用volatile告诉编译器这个变量属于可变的、易变的,编译器遇到volatile修饰的变量时不会对齐进行优化,因为这时优化会造成错误。
(6)restrict
用于限定和约束指针,使用restrict修饰指针,会告诉璧哪一期,所有希望修改该指针指向的内存时,都必须使用该指针才可以进行,目的是让编译器能够更好的优化。
(7)typedef

2 作用域

作用域是描述这个变量起作用的代码范围,C语言变量的作用域规则是代码块作用域,代码块就是{ }括起来的范围,这个变量的作用域是从代码块中变量定义开始往后的部分。

3 生命周期

生命周期是运行时分配内存空间给变量,使用后收回这个内存空间,此后内存地址和这个变量无关。
变量的生命周期指的就是变量何时诞生与何时消亡,诞生是运行时内存中分配变量空间,消亡是内存回收变量空间。
(1)栈变量的生命周期
局部变量空间(自动变量)开辟于栈中,生命周期是临时的,在变量空间代码运行时开辟,运行结束后释放。
(2)堆变量的生命周期
堆变量的生命周期是从malloc申请时诞生,然后使用,直到free时消亡。
(3)数据段、bss段变量的生命周期
全局变量空间开辟于数据段或者bss段中,全局变量的生命周期是永久的,从程序开始运行到终止时都会一直存在。
(4)代码段、只读段的生命周期
程序执行的代码指的是函数,它的生命周期是永久的。

4 链接属性

程序从源代码最终到可执行程序,经历了预编译、编译、汇编、链接。其中编译的目的是把源代码翻译成目标文件,目标文件中有很多符号和代码段、数据段、baa段等分段。符号是编程中的变量名、函数名的等。运行时变量名、函数名能够和相应的内存对应,靠的是符号链接。目标文件链接生成最终可执行程序时,其实就是把符号和相对应的段链接起来。
程序的编译过程就是:编译+链接。编译时将函数、变量变成.o二进制的机器码格式;链接是将各个独立分开的二进制的函数链接起来,形成一个整体的二进制可执行程序。
编译以文件为单位,链接以工程为单位
有多少个.c文件,编译时就会有多少个.o文件,链接后多个.o文件就会变成一个可执行文件。

三种链接属性

(1)外链接
所需的函数与变量可以在外部文件中找到,也就是可以跨文件访问,extern修饰的全局变量和函数就属于外链接。
(2)内链接
所需的函数和变量在当前文件的内部可以找到,对于内链接的函数和变量来说,都是使用static进行修饰。
(3)无链接
符号本身不参与链接,它跟链接没有关系,auto、static都是无链接。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值