单片机全局变量 局部变量 堆与栈 的区别

本文探讨了单片机中局部变量与全局变量的区别,详细分析了它们在内存中的存储方式,以及局部变量如何利用寄存器提高运算效率,全局变量如何在RAM中分配固定地址。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

单片机全局变量 局部变量 堆与栈 的区别

局部变量空间,就是堆栈空间,也就是栈空间。
从局部变量声明的时候,它就在堆栈空间了,而不是调用函数的时候,才让它入栈的。

定义一个局部变量a,编译器会将a的地址分配到寄存器组R0~R7中去。由于它是局部变量,所以编译器将使用立即数赋值语句为代表a的寄存器Rn赋值,最后计算的结果也将存在寄存器组中,位置由编译器任意指定。

定义一个全局变量a,编译器将在RAM中为变量a指定一个专用地址,在C程序中给a赋的值将存入这个专用地址中。程序操作变量a时,首先从专用地址中取出存放的值,然后再进行计算。

结论:

局部变量由于用寄存器直接操作,存取速度和计算速度都很快;由于寄存器数量有限,如果局部变量过多,将使代码由于频繁分配寄存器而变得冗长。

全局变量被定义在内存中的专门地址上,存取位置固定。对于频繁存取的重要变量可以采用全局变量以减少代码的长度;由于全局变量总是占用内存,如果过多,或者把程序处理和计算中的一些中间变量也定义成全局变量,将大量消耗内存空间,处理速度会减慢,同时数据安全性也会降低。

接触过编程的人都知道,高级语言都能通过变量名来访问内存中的数据。那么这些变量在内存中是如何存放的呢?程序又是如何使用这些变量的呢?下面就会对此进行深入的讨论。下文中的C语言代码如没有特别声明,默认都使用VC编译的release版。

首先,来了解一下 C 语言的变量是如何在内存分部的。C 语言有全局变量(Global)、本地变量(Local),静态变量(Static)、寄存器变量(Regeister)。每种变量都有不同的分配方式。先来看下面这段代码:

#include <stdio.h>

int g1=0, g2=0, g3=0;

int main() 

static int s1=0, s2=0, s3=0; 
int v1=0, v2=0, v3=0;

//打印出各个变量的内存地址

printf("0x%08x\n",&v1); //打印各本地变量的内存地址 
printf("0x%08x\n",&v2); 
printf("0x%08x\n\n",&v3); 
printf("0x%08x\n",&g1); //打印各全局变量的内存地址 
printf("0x%08x\n",&g2); 
printf("0x%08x\n\n",&g3); 
printf("0x%08x\n",&s1); //打印各静态变量的内存地址 
printf("0x%08x\n",&s2); 
printf("0x%08x\n\n",&s3); 
return 0; 
}

编译后的执行结果是:

0x0012ff78 
0x0012ff7c 
0x0012ff80

0x004068d0 
0x004068d4 
0x004068d8

0x004068dc 
0x004068e0 
0x004068e4

输 出的结果就是变量的内存地址。其中v1,v2,v3是本地变量,g1,g2,g3是全局变量,s1,s2,s3是静态变量。你可以看到这些变量在内存是连 续分布的,但是本地变量和全局变量分配的内存地址差了十万八千里,而全局变量和静态变量分配的内存是连续的。这是因为本地变量和全局/静态变量是分配在不 同类型的内存区域中的结果。对于一个进程的内存空间而言,可以在逻辑上分成3个部份:代码区,静态数据区和动态数据区。动态数据区一般就是“堆栈”。“栈 (stack)”和“堆(heap)”是两种不同的动态数据区,栈是一种线性结构,堆是一种链式结构。进程的每个线程都有私有的“栈”,所以每个线程虽然 代码一样,但本地变量的数据都是互不干扰。一个堆栈可以通过“基地址”和“栈顶”地址来描述。全局变量和静态变量分配在静态数据区,本地变量分配在动态数 据区,即堆栈中。程序通过堆栈的基地址和偏移量来访问本地变量。

### 单片机全局变量局部变量区别 #### 定义位置 在单片机编程环境中,全局变量是在任何函数之外定义的变量。这些变量在整个程序生命周期内都存在,并且可以从程序中的任意位置访问[^4]。 而局部变量则是在某个特定函数或代码块内部定义的变量。它们仅在其被定义的那个作用域内有效,在该作用域外无法直接访问[^1]。 #### 生命周期和存储区域 对于全局变量而言,其生命周期贯穿整个应用程序运行期间。当程序启动时,全局变量会在数据段(已初始化)或BSS段(未初始化,默认值为零)分配空间并初始化[^5]。 相反,局部变量通常位于上,每次进入相应的函数调用时创建,离开此函数时销毁。这意味着局部变量只存在于函数执行的过程中。 #### 访问权限及影响 由于全局变量具有更广泛的可访问性,这可能导致更高的模块间耦合度,使得维护更加困难。因此,在某些情况下减少甚至避免使用全局变量被认为是良好实践的一部分[^2]。 另一方面,局部变量因为受限于较小的作用范围,有助于降低复杂性和提高代码清晰度。然而需要注意的是如果同名局部变量遮蔽了相同名称下的全局变量,则后者在此处将不可见。 ```c // 示例展示全局变量局部变量的不同特性 #include <stdio.h> int globalVar = 10; // 全局变量 void exampleFunction(void){ int localVar = 20; // 局部变量 printf("Global Variable Value Inside Function: %d\n",globalVar); printf("Local Variable Value Inside Function: %d\n",localVar); } int main(){ printf("Global Variable Value Outside Function: %d\n",globalVar); exampleFunction(); // 下面这一行会产生编译错误,因为我们试图在外层访问局部变量 //printf("Trying to access local variable outside its scope:%d\n",localVar); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值