【STM32单片机入门-1】堆栈/全局变量,局部变量,静态全局变量,局部静态变量等

1,堆栈对比

堆:由程序员分配和释放。容易产生碎片,使用方便,地址分配使用从下到上

栈:用来存放函数地址和局部参数,主函数使用时,要对函数的首地址断点保存,地址分配从上到下,用完自动释放

  • 0x2001,0000往下是未用的空间,可以做栈空间,只要不破坏全局变量,地址由程序员配置

2,静态存储区/全局变量/全局静态变量

静态存储区:它主要存放静态数据、全局数据和常量。

全局变量:全局变量存放在静态存储区,作用域是全局,整个声明周期都可以使用,其他文件如需要使用,需要添加extern

全局静态变量 (static):分配的内存与全局变量一样,也是在静态存储内存上,其生命周期也是与整个程序同在的,从程序开始到结束一直起作用,

全局静态变量作用域只在定义它的一个源文件内,其他源文件不能使用它

相同点

是由编译器自动分配和释放的,

初始化的全局变量和静态变量放在同一块内存区中

在调用main之前,内存先从FASH copy 数据(全局/静态变量),和复制全0段的(全局/静态变量)

全局变量和静态变量从0x2000,000开始存

3,局部变量和局部静态变量

分配内存是分配在栈存储区上的,其作用域也只是在局部函数内,在定义该变量的函数内,只要出了该函数,该局部变量就不再起作用,该变量的生命周期也只是和该函数同在。

局部变量

在栈里,临时给a 分配空间,

局部静态变量

分配的内存也是在静态存储内存上的,其第一次初始化后就一直存在直到程序结束,该变量的特点是其作用域只在定义它的函数内可见,出了该函数就不可见了。

4,代码举例

volatile int a = 0;// 全局初始化区  ①存放在内存起始单元0x2000,0000 
volatile char *p1; //全局未初始化区 ②存放在起始单元00x2000,0004 
void test(void)
{
    volatile  int t1=10;   //局部变量                      ④存放在栈空间  0x2000,0600  
    volatile static int t2 =0;//局部静态变量          ③存放在起始单元0x2000,0008     
 //    printf("%d %d  ",t1,t2);//防止代码被优化
}
void main()
{
    
    volatile int b  = 0;                                      //栈       ⑥存放在栈空间  0x20000620
    volatile char s[] = "abc";                        // 栈                ⑤存放在栈空间  0x2000061C 
    volatile char *p2;                                      //栈          存放在堆空间  0x20000618 
    volatile char *p3 = "123456";               //123456\0在常量区,p3在栈上。 0x20000614  
    volatile static int c =0;              //局部(静态)初始化区 ④存放在起始单元00x2000,000c
    test();
    
    //分配得来得10和20字节的区域就在堆区。
     p1 = (char *)malloc(10);
     p2 = (char *)malloc(20);
    volatile char *p4= (char *)malloc(20);  //存放在堆空间 0x20000610
    strcpy(p2, "123456");                                 //123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。
    
    printf("%d %d %d %d  %d %d  %d ",a,s[0],&p3,c,p1,b,&p2,&p4);//防止代码被优化
}

来自文心一言的解答

这段代码中的变量存储位置以及内存分配涉及到C语言的内存布局和内存管理。首先,我们逐一回答您的问题。

  1. t1存放在栈空间中,请问栈空间的起始地址在哪里配置的?

栈空间的起始地址和大小通常是在程序启动时由操作系统配置的。具体的配置方式依赖于操作系统和硬件架构。在嵌入式系统或低级编程中,可能会直接设置栈指针寄存器来指定栈的起始和结束位置。在高级操作系统中,如Linux或Windows,这通常是进程创建时的一部分自动管理。

2. p2,p3,p4 都是堆空间分配地址的吗?

p2p4 是通过 malloc 分配的,所以它们指向的地址是在堆空间中的。而 p3 是一个指向字符串常量 "123456" 的指针,这个字符串常量通常存放在程序的常量区,不是堆空间。

3. 这个地址位置也和栈在一个地址范围吗?

不一定。堆和栈通常是两个不同的内存区域,它们有自己的起始和结束地址。具体的位置和大小取决于操作系统、编译器设置和硬件架构。在某些架构和操作系统中,堆和栈可能是相邻的,但它们仍然是逻辑上分离的区域。

现在,关于代码中的内存布局:

ap1 是全局变量,它们存放在全局/静态存储区。

t1 是局部变量,存放在当前函数的栈帧中。

t2 是局部静态变量,存放在全局/静态存储区,但其生命周期局限于定义它的函数内。

b, s, p2, p3, 和 c 都是在 main 函数内的局部变量。其中,sb 存放在栈上;p2p3 本身存放在栈上,但它们通过 malloc 分配的内存位于堆上;c 是局部静态变量,存放在全局/静态存储区。

p4 也是一个局部变量,存放在栈上,但通过 malloc 分配的内存位于堆上。

请注意,具体的内存地址(如0x2000,0000、0x2000,0004等)在代码中只是示例,实际运行时可能会有所不同。另外,当您提到 "防止代码被优化" 时,使用 volatile 和打印变量的方式确实可以防止某些编译器优化,但这不是一个通用的或推荐的方法。更好的方法是使用适当的编译器优化设置和/或编译器特定的属性或注解来确保代码的正确性和性能。

5,总结

  • 36
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个示例程序,其中包含局部变量全局变量、全局静态变量局部静态变量以及函数: ```c++ #include <iostream> // 全局变量 int globalVar = 10; // 全局静态变量 static int globalStaticVar = 20; // 函数声明 void exampleFunction(); int main() { // 局部变量 int localVar = 30; std::cout << "Global variable value: " << globalVar << std::endl; std::cout << "Global static variable value: " << globalStaticVar << std::endl; std::cout << "Local variable value: " << localVar << std::endl; exampleFunction(); exampleFunction(); exampleFunction(); return 0; } // 函数定义 void exampleFunction() { // 局部静态变量 static int staticVar = 0; // 输出各个变量的值 std::cout << "Global variable value: " << globalVar << std::endl; std::cout << "Global static variable value: " << globalStaticVar << std::endl; std::cout << "Static variable value: " << staticVar << std::endl; // 将静态变量递增 staticVar++; } ``` 在这个程序中,我们定义了一个全局变量 `globalVar` 和一个全局静态变量 `globalStaticVar`,它们可以在程序的任何地方访问。在 `main()` 函数中,我们定义了一个局部变量 `localVar`,它只能在 `main()` 函数中访问。 我们还定义了一个函数 `exampleFunction()`,其中包含一个局部静态变量 `staticVar`,它只能在 `exampleFunction()` 函数内部访问。 在 `main()` 函数中,我们输出了各个变量的值,并调用了三次 `exampleFunction()` 函数。在 `exampleFunction()` 函数中,我们输出了各个变量的值,并将静态变量 `staticVar` 递增。 运行结果如下所示: ``` Global variable value: 10 Global static variable value: 20 Local variable value: 30 Global variable value: 10 Global static variable value: 20 Static variable value: 0 Global variable value: 10 Global static variable value: 20 Static variable value: 1 Global variable value: 10 Global static variable value: 20 Static variable value: 2 ``` 我们可以看到,全局变量、全局静态变量局部变量在任何地方都可以访问,而局部静态变量只能在函数内部访问。同时,全局变量和全局静态变量的值在整个程序的生命周期中都是保持不变的,而局部变量局部静态变量的值只在函数调用期间存在。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值