C 语言中的内存地址
C 语言中的内存地址
在 C 语言中,内存地址会在变量声明时赋值给该变量。 C 编译器将变量的值存储在内存的不同段中。
内存段
C 程序的不同元素存储在计算机内存的不同段中,内存包含以下段:
- 文本段 − 文本段,也称为代码段或简称为文本,是程序中用于存储 C 程序对象版本的部分之一。
- 初始化数据段 − 由以下程序段初始化的全局变量和静态变量程序员在初始化数据段中分配内存。
- 未初始化数据段 − 未初始化数据段也称为bss(代表block started by symbol)。程序加载时会为此段分配内存。在 C 程序执行之前,内核会将bss中的所有数据初始化为算术"0",并将指针初始化为空指针。
- 堆栈 − 堆栈是一种 LIFO(后进先出)数据结构。堆栈段存储局部变量的值以及传递给函数的参数的值。它还维护函数调用返回的指针。
- 堆 − 堆用于在运行时分配内存。所有执行动态内存分配的函数都与堆有关。
访问内存地址
C 语言中的内存地址可以通过地址 (&) 运算符访问或指定。要使用 printf() 函数 打印内存地址,需要使用 %p 格式说明符。
语法
以下是访问内存地址的语法 -
&variable_name
示例
在下面的示例中,我们声明两个变量并打印它们的内存地址 -
#include <stdio.h> int main() { // 声明两个变量 int a; int b; // 访问它们的内存 // 地址并打印它们 printf("Memory address of a is %p ", &a); printf("Memory address of b is %p ", &b); return 0; }
C 编译器如何分配内存?
内存可以看作是一个字节数组,每个地址位于数组的索引上,并占用 1 个字节。
在 C 程序中声明变量时,C 编译器会根据变量的大小需求(取决于变量的类型)为其分配一个随机的内存位置。
声明 int 变量时 -
int x = 10;
编译器会将值赋值到一个随机的字节地址中。由于 int 类型需要 4 个字节,因此接下来的 4 个地址会被分配给它。
C 语言允许你查找已分配给变量的地址。您可以使用 %p 格式说明符打印内存位置的十六进制地址。
char x = 'A'; printf ("x 的地址: %p ", &x);
这将以十六进制格式打印"x"的地址 -
x 的地址:000000000061FE1F
示例
C 语言中的数组是连续的内存区域,用于保存多个相同数据类型(int、long、*char 等)的值。
#include <stdio.h> int main() { // 初始化一个 int 数组 int numbers[5] = {1,2,3,4,5}; int i = 0; // 打印数组变量的地址 printf("numbers = %p ", numbers); // 打印每个数组索引的地址 do { printf("numbers[%u] = %p ", i, (void *)(&numbers[i])); i++; } while(i < 5); // 打印数组的大小 printf("sizeof(numbers) = %lu ", sizeof(numbers)); }
输出
运行此代码时,将产生以下输出 -
numbers = 0x7fff0815c0e0 numbers[0] = 0x7fff0815c0e0 numbers[1] = 0x7fff0815c0e4 numbers[2] = 0x7fff0815c0e8 numbers[3] = 0x7fff0815c0ec numbers[4] = 0x7fff0815c0f0 sizeof(numbers) = 20