局部变量和函数参数通常存储在栈中。函数调用时,栈空间用于存储函数参数、返回地址和局部变量。

int func(const char *str1, char *str2, int count) 
{
  count++;
  printf("%s %s\n", str1, str2);
  return count;
}

在这个函数中,参数,局部变量都是存储在栈上的,等函数返回后,栈就会销毁,这些变量也会被释放,所以函数外访问不到他们

注意这里有两个参数是指针,表示是引用传递,但这并不意味这你就能修改他们,加上const关键字修饰参数(限制对变量的修改),可以保护这个变量不被修改,如果不加,你也要考虑到实际参数是否可以被修改,即实际参数是否是个常量

动态分配的内存(使用 malloc、calloc 等)存储在堆中。堆内存的生命周期是由程序员控制的。

char *p = malloc(2 * sizeof(char));
free(p);

p也是一个变量,但它并不存储在堆区中,它只是指向堆中分配的内存

全局/静态存储区

静态变量和全局变量存储在静态存储区,生命周期从程序开始到结束。

int global_v = 0; // 全局变量
void func()
{
  static local = 1; // 静态变量,只会初始化一次
}

常量区

字面量常量和一些常量数据存储在常量区。

  • 字符串字面量,比如"hello"
  • 使用 const 修饰的变量,比如const int a;
  • 编译时常量(如 #define 和 enum)

特殊

void func()
{
  char *str1 = "hello"; // 常量区
  char str2[] = "world"; // 栈
}

在上述这个例子中,str1和str2都是局部变量,但是str1指向的"hello"是存储在常量区的,str1这个指针指向他,str2是一个数组,"world"以数组的形式存储在栈上,即{'w', 'o', 'r', 'l', 'd', '\0'}这6个字节,函数返回后会被销毁

主要的原因还是,编译器对他们的解释不同吧,一个解释为字符串常量,一个解释为数组

补充

  • 静态局部变量会存储在bss区(也是静态存储区),如果没有显示初始化,会自动初始化为0
  • 普通局部变量只有在函数调用时才会分配内存,分配在栈帧上
  • 变量即使没有初始化,仍旧会为他分配空间,只不过值是未定义的
 posted on 2024-10-06 14:03  Dylaris  阅读(152)  评论(0)    收藏  举报