从单片机角度看堆栈及部分延伸问题

   本文章为网络资源摘抄与总结,能力有限,有错误与漏洞希望大佬们给予提示或帮助,感谢…


   

一、堆栈的相关概念

(1)栈区(stack):由编译器自动分配和释放,存放函数的参数值、局部变量的值等,其操作方式类似
于数据结构中的栈。
(2)堆区(heap):一般由程序员分配和释放,若程序员不释放,程序结束时可能由操作系统回收。分配
方式类似于数据结构中的链表。
(3)全局区(静态区)(static)全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系
统自动释放。
(4)文字常量区常量字符串就是存放在这里的。
(5)程序代码区:存放函数体的二进制代码

以下是概念结构图
在这里插入图片描述


   二、静态、全局变量概念 (static/extern)

   普通局部变量是再熟悉不过的变量了,在任何一个函数内部定义的变量(不加static修饰符)都属于这个范畴。编译器一般不对普通局部变量进行初始化,也就是说它的值在初始时是不确定的,除非对其显式赋值。

普通局部变量存储于进程栈空间,使用完毕会立即释放。

静态局部变量使用static修饰符定义,即使在声明时未赋初值,编译器也会把它初始化为0。且静态局部变量存储于进程的全局数据区,即使函数返回,它的值也会保持不变。

    变量在全局数据区分配内存空间;编译器自动对其初始化,其作用域为局部作用域,当定义它的函数结束时,其作用域随之结束全局变量定义在函数体外部,在全局数据区分配存储空间,且编译器会自动对其初始化。

普通全局变量对整个工程可见,其他文件可以使用extern外部声明后直接使用。也就是说其他文件不能再定义一个与其相同名字的变量了(否则编译器会认为它们是同一个变量)。
静态全局变量仅对当前文件可见,其他文件不可访问,其他文件可以定义与其同名的变量,两者互不影响。


三、在程序运行下,堆栈示例

int a=0;   //全局初始化区
char *p1;   //全局未初始化区
main()
{
int b;   //栈
char s[]="abc";   //栈
char *p3= "123456";   //在文字常量区Flash
static int c =0 ;   //静态初始化区
p1= (char *)malloc(10);   //堆区
strcpy(p1,"123456");   //"123456"放在常量区
}  

按程序顺序解释操作
   1、定义了a整形变量,a入栈(先入后出),全局初始化区分配地址存入数据0,因为此操作不在括号内,所以此部分程序运行结束也不存在出栈与内存释放。
   2、定义了p1指针变量,p1入栈(先入后出),全局未初始化区分配地址,因为此操作不在括号内,所以此部分程序运行结束也不存在出栈与内存释放。
   3、定义了b整形变量,b入栈(先入后出),栈区分配地址,因为此操作在括号内,所以此部分程序运行结束存在出栈与内存释放。
   4、定义了数组s,s入栈(先入后出),栈区分配地址,存入“abc” 因为此操作在括号内,所以此部分程序运行结束存在出栈与内存释放。
   5、定义了字符指针p3,p3入栈(存入的是首地址),123456/0在常量区,因为此操作在括号内,所以此部分程序运行结束存在出栈与内存释放。
   6、定义了静态局部整形变量c,入栈(先入后出),静态初始化区分配地址存入数据0,因为是静态局部变量,所以此部分程序运行结束不存在内存释放。
   7、在堆区申请长度为10字节的连续存储空间,并将分配到的存储空间地址转换为char类型地址,然后把他赋给指针变量p1。
   8、拷贝123456/0在栈区,并放入到目标p3首地址中,123456/0放在常量区,因为之前存入过同样的数据,编译器可能会将它与p3所指向的"123456" 优化成一个数据地址。节省了空间。


四、延伸问题

   const 有什么用途?
   const:限定变量的权限,变成只读(不能做左值)。左值:写权限 右值:读权限
   1.基本数据类型对于const透明。
   2.const修饰它的直接右边。
    const int*p=&a;=>int const *p1=&a;
    *p1=1000;//出错,*p1不能做左值
   3.权限可以同等或者缩小传递,但不能放大传递。

   嵌入式C语言中volatile的用途?
   一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:

  1. 并行设备的硬件寄存器(如:状态寄存器
  2. 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
  3. 多线程应用中被几个任务共享的变量

   大端存储与小端存储?
   大端(存储)模式:是指一个数据的低位字节序的内容放在高地址处,高位字节序存的内容放在低地址处。
   小端(存储)模式:是指一个数据的低位字节序内容存放在低地址处,高位字节序的内容存放在高地址处。(可以总结为“小小小”即低位、低地址、小端)

32位的数据0x12345678从地址0x20000000开始存储,小端和大端的存储区别如下图
在这里插入图片描述
未完待续。。。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值