您的位置:首页 > 编程语言 > C语言/C++

嵌入式学习10(C语言五大内存区间,变量的作用域和生存期,变量的存储类型)

2017-07-18 16:16 1056 查看
今天又是元气满满的一天


C语言的五大内存区间

1、  栈区(stack):函数的形参和局部变量,先入后出,由编译器自动分配,自动释放

2、  堆区(heap):一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它和数据结构中的堆是两回事,分配方式类似与链表(malloc---free ;new—delete)

3、  全局区(静态区)(static):全局变量和静态变量是存放到一起的,初始化的全局和静态在一块区,未初始化的在相邻的另一块区域。系统释放。

4、  文字常量区:存放常量字符串,系统释放。

5、  代码区:存放函数体的二进制代码

 

 

 

变量的作用域和生存期(两种分类方式)

按作用域分:

(1)      局部变量

Ø  局部和全局重名时,屏蔽同名全局

Ø  不同作用域的局部变量可以重名

 

(2)      全局变量:作用域是整个源程序,在函数中使用全局变量,一般作全局说明。但在一个函数之前定义的全局变量,在函数体内不用再加说明。

Ø  用extern关键字定义的全局变量称为外部变量。可将作用域进行扩充(本源文件或其他源文件)。

Ø  使用static关键字可以将其作用域限定在其所在源文件,这样就和其他源文件中的同名全局变量不冲突了

 

按生存期分:

(1)静态存储方式:全局变量,静态变量

(2)动态存储方式:函数开始调用时分配动态存储空间,函数结束时释放这些空间。

          Ø  函数的形参

          Ø  自动变量(auto):未加static声明的局部变量

            int  a=90;等价于autoint  a=90;系统默认,可省略

          Ø  函数调用时的现场保护和返回地址(与汇编中的中断相关)

 

 

 

 

 

在c语言中,每个变量和函数有两个属性:数据类型和数据的存储类别。

4中变量存储类型

auto :声明为自动变量(动态存储)

register:声明为寄存器变量(动态存储)

extern:声明为外部变量(静态存储)

static:声明为静态变量(静态存储)

 

 

auto:关键字auto可以省略,auto不写则隐含定为“自动存储类别”

register变量(寄存器变量):将局部变量的值放在CPU中的寄存器中,提高效率。

只有栈区的变量能作寄存器变量。寄存器数目有限,不能定义任意多个

extern:声明外部变量,扩充作用域

static:

静态局部变量和普通局部变量的区别

1)  静态局部变量属于静态存储类别,在静态存储区内分配存储单元。在程序整个运行期间都不释放。而自动变量(即动态局部变量)属于动态存储类别,占动态存储空间,函数调用结束后立即释放。

2)  静态局部变量在编译时赋初值,即只赋初值一次;而对自动变量赋初值是在函数调用时进行,每调用一次函数重新给一次初值,相当于执行一次赋值语句。

3)  如果在定义局部变量时不赋初值的话,则对静态局部变量来说,编译时自动赋初值0(对数值型变量)或空字符(对字符变量)。而对自动变量来说,如果不赋初值则它的值是一个不确定的值。

 

 

补充两种类型

volatile:

         对于经常使用的变量,若无特别说明,编译器会优化,将变量数据放到寄存器中,以提高读取效率。

volatile声明变量在程序执行中,可被隐含的改变(拒绝编译器的优化)

         告诉编译器修饰的变量是随时变化的,每次使用都必须从内存中去取出它的值。如果一个寄存器或变量,表示一个端口或者多个线程的共享数据,需要用volatile,保证对特殊地址的访问。

         变量如果加了volatile修饰,则会从内存中重新装载内容,而不是直接从寄存器中拷贝内容。

 

const:只读

 

 

malloc原理(扩充知识点)

  malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表。调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块。然后,将该内存块一分为二(一块的大小与用户请求的大小相等,另一块的大小就是剩下的字节)。接下来,将分配给用户的那块内存传给用户,并将剩下的那块(如果有的话)返回到连接表上。调用free函数时,它将用户释放的内存块连接到空闲链上。到最后,空闲链会被切成很多的小内存片段,如果这时用户申请一个大的内存片段,那么空闲链上可能没有可以满足用户要求的片段了。于是,malloc函数请求延时,并开始在空闲链上翻箱倒柜地检查各内存片段,对它们进行整理,将相邻的小空闲块合并成较大的内存块。如果无法获得符合要求的内存块,malloc函数会返回NULL指针,因此在调用malloc动态申请内存块时,一定要进行返回值的判断。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言 嵌入式学习
相关文章推荐