概述
c语言从0开始_8 变量 进程映像 类型限定符
- 进程映像
- text 代码段
- data 数据段
- bss 静态数据段
- heap 堆
- stack 栈
- 变量
- 全局变量
- 静态全局变量
- 局部变量
- 静态局部变量
- 块变量
- 注意
- 类型限定符
- auto
- const
- extern
- static
- register
- volatile
- typedef
进程映像
程序:储存在磁盘中的可执行的文件(二进制文件、脚本文件)
进程:在系统中运行的程序
进程映像:进程的内存的分布情况
text 代码段
存储的是二进制的指令、常量数据,权限是只读的,如果强行修改会产生段错误
data 数据段
存储的是初始化过的全局变量、被初始化过的静态局部变量
bss 静态数据段
存储的是未初始化过的全局变量、未初始化过的静态局部变量,该内存段在程序执行前会被初始化为0。
heap 堆
由于程序员手动管理,该内存无法与标识符建立映射关系(无法取名字),必须与指针配合使用。
优点:够大,分配和释放可控。
缺点:使用麻烦,容易产生内存泄漏、内存碎片。
stack 栈
由系统自动管理,随着函数被调用,会自动分配内存,函数执行结束后自动释放内存。
优点:使用方便,采用栈结构方式管理安全,不会产生内存泄漏、内存碎片。
缺点:大小有限,一次使用过多可能会产生段错误,分配和释放不可控不适合
变量
变量的属性:存储位置 生命周期 作用域
全局变量
定义在函数外的变量
存储位置: data(初始化过的)或者bss(未初始化过的)
生命周期: main函数运行开始前到程序结束才释放,即整个程序的运行时期
作用范围: 程序中的任何位置,其它源文件中需要声明
静态全局变量
存储位置:data 初始化过的,bss 未初始化的
生命周期:整个程序的运行时期
作用范围:在目标文件内可以使用
局部变量
定义在函数内的
存储位置: stack栈内存
生命周期: 函数的定义语句开始,直到函数执行结束
作用范围:只能在本函数内使用
静态局部变量
存储位置:data 初始化过的,bss 未初始化的
生命周期:整个程序的运行时期
作用范围:函数内
块变量
定义在ifforwhile等语句块内的变量
存储位置: stack栈内存
生命周期: 函数的定义语句开始,直到函数执行结束
作用范围:只能在语句块内使用
注意
局部变量和全局变量可以同名,但是会屏蔽同名的全局变量,同名块变量会屏蔽同名的局部变量和全局变量
建议:全局变量首字母大写
类型限定符
auto
用于定义自动申请、自动释放的变量(局部变量),不加代表了加。早期用于定义临时变量(局部变量和块),C11标准中它可以用于定义自动推导类型的变量。现在看来没什么用。只有在使用时才为该类型变量分配内存。
不能用于修饰全局变量
const
显示地"保护"变量不被修改
但是,如果要强制修改还是可以修改的
如果对初始化过的全局变量,用const修饰后,存储位置从data变成了text
extern
声明外部的全局变量,声明的变量已在别处定义过,请放心使用
但是只能临时通过编译,如果没有定义,链接时依然会报错
只是声明变量,不能赋值
static
被static修饰过的变量称为静态局部变量,局部全局变量
改变存储位置:
改变局部变量的存储位置,由stack改data或者bss(由是否初始化决定)
延长生命周期:
延长局部变量的生命周期
限制作用范围:
限制全局变量、函数只能在本文件内使用
可以防止函数、全局变量重名、防止被别人调用
register
存储介质:
硬盘->内存->高速缓存->寄存器->CPU
申请把变量的存储介质由内存转移到寄存器存储,如果能成功,数据的读取速度会大幅提升,寄存器数量有限,申请可能失败
好处:
register修饰符暗示编译程序相应的变量将被频繁地使用,如果可能的话,应将其保存在CPU的寄存器中,以加快其存储速度。
register修饰符有几点限制;
1.register变量必须是一个单个的值,并且长度应该小于或者等于整型的长度。不过,有些机器的寄存器也能存放浮点数。
2.因为register变量可能不存放在内存中,所以不能用“&”来获取register变量的地址。
3.只有局部自动变量和形式参数可以作为寄存器变量,其它(如全局变量)不行。
4.局部静态变量不能定义为寄存器变量。不能写成:register static int a, b, c;
5.由于寄存器的数量有限(不同的cpu寄存器数目不一),不能定义任意多个寄存器变量,而且某些寄存器只能接受特定类型的数据(如指针和浮点数),因此真正起作用的register修饰符的数目和类型都依赖于运行程序的机器,而任何多余的register修饰符都将被编译程序所忽略。
volatile
编译器的取值优化:
变量的值没有发生改变时,后续的取值会进行优化,不再去内存中读取,而是使用第一次读取的结果,可以节约时间
使用volatile修饰的变量不做取值优化
volatile int num = 10;
if(num == num)
{
//可能为假
}
一般硬件编程和驱动编程时使用
typedef
类型重定义,注意不是替换关系,定义变量时如果前面加上typedef,则变量名就变成了类型
typedef int num;
#define num int;
num num2;
uint8_t size_t time_t
typedef unsigned char uint8_t
最后
以上就是高高龙猫为你收集整理的c语言从0开始_8 变量 进程映像 类型限定符进程映像变量类型限定符的全部内容,希望文章能够帮你解决c语言从0开始_8 变量 进程映像 类型限定符进程映像变量类型限定符所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复