Cprogramming 简明教程

Memory Address in C

Memory Address in C

当用 C 语言声明变量时, memory address 会被分配给变量。 C compiler 将变量的值存储在内存的不同段中。

Segments of Memory

C 程序的不同元素存储在计算机内存的不同段中,这些段具有以下内容 -

  1. Text segment - 文本段,也称为 code segment 或简称为 text ,是 progris 的一个部分,用于存储 C 程序的对象版本。

  2. Initialized data segment - 由程序员初始化的 global variablesstatic variables 被分配到已初始化的数据段中的内存。

  3. Uninitialized data segment - 未初始化的数据段也称为 bss (代表 block started by symbol )。程序在其加载时,为该段分配内存。 bss 中的每个数据在 C 程序执行之前都由内核初始化为算术“0”,指针指向空指针。

  4. Stack - 栈是 LIFO(后进先出)数据结构。栈段存储局部变量的值和传递给函数的参数的值。它还维护指向函数调用返回的指针。

  5. Heap - 堆用于在运行时分配内存。对动态内存分配执行操作的所有函数都处理堆。

Accessing Memory Address

可以通过 Address of (&) operator 访问或指定 C 中的内存地址。要使用 printf() function 打印内存地址,您需要使用 %p 格式说明符。

Syntax

下面是访问内存地址的语法 -

&variable_name

Example

在以下示例中,我们声明了两个变量并打印它们的内存地址 -

#include <stdio.h>

int main() {
   // Declaring two variables
   int a;
   int b;

   // Accessing their memory
   // addresses and print them
   printf("Memory address of a is %p\n", &a);
   printf("Memory address of b is %p\n", &b);

   return 0;
}

How Does C Compiler Allocate Memory?

可以将内存视为一个字节数组,其中每个地址都是数组中的索引,并包含 1 个字节。

当您在 C 程序中声明一个变量时,C 编译器根据大小要求为其分配一个随机的内存位置,而大小要求又取决于类型。

当声明 int 变量时 -

int x = 10;

编译器在随机字节地址中分配值。由于 int 类型需要 4 个字节,因此为它预留了接下来的四个地址。

C 允许你找出已分配给某变量的地址。你可以使用 %p 格式说明符在内存位置的 16 进制格式中打印地址。

char x = 'A';
printf ("address of x: %p\n", &x);

这将以 16 进制格式打印“x”的内存地址:

Address of x: 000000000061FE1F

Example

Arrays in C 是连续的内存区域,这些内存区域包含一定数量相同数据类型(int、long、*char 等)的值。

#include <stdio.h>

int main() {

   // initialize an array of ints
   int numbers[5] = {1,2,3,4,5};
   int i = 0;

   // print the address of the array variable
   printf("numbers = %p\n", numbers);

   // print addresses of each array index
   do {
      printf("numbers[%u] = %p\n", i, (void *)(&numbers[i]));
      i++;
   } while(i < 5);


   // print the size of the array
   printf("sizeof(numbers) = %lu\n", sizeof(numbers));
}

当你运行这段代码时,它将产生以下输出:

numbers = 0x7fff0815c0e0
numbers[0] = 0x7fff0815c0e0
numbers[1] = 0x7fff0815c0e4
numbers[2] = 0x7fff0815c0e8
numbers[3] = 0x7fff0815c0ec
numbers[4] = 0x7fff0815c0f0
sizeof(numbers) = 20