下面是“C语言数据的存储超详细讲解上篇”完整攻略。
一、内存模型
在C语言中,程序中的数据都是存储在内存中的。内存是按照字节进行划分的,每个字节都有一个唯一的地址。程序可以通过地址来访问内存中的数据。
C语言中的内存模型分为以下几个不同的部分:
栈
栈是一种数据结构,它是一个先进后出(LIFO)的结构。栈的大小是可以动态变化的,它和函数的调用有着密切的关系。
当一个函数被调用时,它的参数、返回地址以及一些寄存器都会被压入栈中。函数执行结束后,它们也会被弹出。
在栈中,变量的分配是连续的,因此可以通过栈指针进行内存地址的计算。这也是栈的优势之一。
堆
堆是一种动态内存分配的机制,它的大小可以在运行时动态地改变。我们通常使用mallo
函数从堆上动态地分配内存。
堆中的内存分配不是连续的,也就是说,没有办法通过指针偏移来访问。
在堆中分配的内存需要手动释放,否则就会发生内存泄漏。
数据段
数据段是一个存储全局变量和静态变量的区域。它分为两个部分:
- BSS段:用来存放未被初始化的全局变量和静态变量;
- 数据段:用来存放已经被初始化的全局变量和静态变量。
代码段
代码段存储着程序的代码,它通常是只读的。执行程序时,代码段中的指令会被载入到CPU中,进行执行。
二、示例
下面是两个示例,它们分别演示了存储在不同内存模型中的数据的不同。代码如下:
示例1
#include <stdio.h>
#include <stdlib.h>
char* str = "Hello World"; // 全局变量,存储在数据段中
void f() {
char* s = "Hello China"; // 局部变量,存储在栈中
printf("%s\n", s);
}
int main() {
char* p = malloc(sizeof(char) * 100); // 动态内存分配,存储在堆中
strcpy(p, str);
printf("%s\n", p);
f();
return 0;
}
在这个示例中,我们定义了一个全局变量,将它存储在数据段中。同时,在函数中定义了一个局部变量,将它存储在栈中。在main
函数中,我们使用malloc
函数从堆中动态地分配了一块内存。
运行这个程序后,我们可以看到输出了如下内容:
Hello World
Hello China
这是因为在函数调用的过程中,函数参数、返回地址等信息都被压入栈中。
示例2
#include <stdio.h>
#include <stdlib.h>
int main() {
int a = 10; // 栈区
int b[10]; // 栈区
char* p = "Hello World"; // 常量区
char str[] = "Hello"; // 栈区
static int c = 30; // 数据区
int *q = (int *)malloc(sizeof(int));
*q = 20; // 堆区
printf("a: %p\n", &a);
printf("b: %p\n", b);
printf("p: %p\n", p);
printf("str: %p\n", &str);
printf("c: %p\n", &c);
printf("q: %p\n", q);
free(q);
return 0;
}
在这个示例中,我们定义了不同类型的、存储在不同内存模型中的变量,并使用了一些函数来打印变量的地址。
运行程序后,我们可以得到如下输出:
a: 0x7fff6e79e32c
b: 0x7fff6e79e320
p: 0x106920f26
str: 0x7fff6e79e30e
c: 0x106920f20
q: 0x7facbf400b40
从输出中可以看出,不同类型的变量存储在不同的内存模型中。同时,我们也可以通过地址来判断一个变量存储在哪个内存模型中。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言数据的存储超详细讲解上篇 - Python技术站