3813

19 分钟

#C 语言的指针

指针是 C 语言中的一个重要概念,在类型名称后面添加一个星号(*)来表示对应的指针类型,例如 int* 表示指向 int 类型的指针。

指针类型的变量中保存的是内存地址,指针的类型表示如何解读该内存中的值。

示例:

#include <stdio.h> int main(void) { int* ptr = (int*)4; // 定义整型指针 ptr,它的初始值为 4 printf("指针指向地址为 %p 的内存\n", ptr); // 通过 %p 打印指针本身 printf("该内存里的整型值为 %d\n", *ptr); // *ptr 取值,因为 ptr 的类型是 int* 因此按照 int 类型进行取值 *ptr = 8080; // 将该内存地址中的值修改为 8080 printf("该内存里的整型值被修改为 %d\n", *ptr); // *ptr 取值,因为 ptr 的类型是 int* 因此按照 int 类型进行取值 return 0; }

说明:

  • printf 函数使用 %p 打印指针类型本身
  • *ptr 中的 *间接访存运算符,有时也称 解引用运算符,即访问内存中地址为 ptr 处的值

内存

地址:0
值:1000

地址:4
值:2333

地址:8
值:6666

ptr

运行结果:

指针指向地址为 0x2 的内存 该内存里的整型值为 2333 该内存里的整型值被修改为 8080

上述代码在现代操作系统上是无法运行的。因为现代操作系统使用保护模式,应用程序不能直接访问整个内存,只能间接访问部分内存。

示例:

#include <stdio.h> int main(void) { int x = 2333; // 定义整型变量 x int* ptr = &x; // 定义整型指针 ptr,它的初始值为变量 x 的地址 printf("指针指向地址为 %p 的内存\n", ptr); // 通过 %p 打印指针本身 printf("该内存里的整型值为 %d\n", *ptr); // *ptr 取值,因为 ptr 的类型是 int* 因此按照 int 类型进行取值 *ptr = 8080; // 将该内存地址中的值修改为 8080 printf("该内存里的整型值被修改为 %d\n", *ptr); // *ptr 取值,因为 ptr 的类型是 int* 因此按照 int 类型进行取值 return 0; }

说明:

  • printf 函数使用 %p 打印指针类型本身
  • &x 中的 &取地址运算符,有时也称 引用运算符,即获取变量在内存中的地址
  • *ptr 中的 *间接访存运算符,有时也称 解引用运算符,即访问内存中地址为 ptr 处的值

内存

变量:x
值:2333

ptr

运行结果:

指针指向地址为 0x7ffe9e866f2c 的内存 该内存里的整型值为 2333 该内存里的整型值被修改为 8080

#指针的运算

指针中保存的是内存地址,本质上是一个整数,因此指针可以进行计算。

示例:

#include <stdio.h> int main(void) { int* ptr = (int*)4; // 定义整型指针 ptr,它的初始值是 4 printf("ptr 指向地址为 %p 的内存\n", ptr); // 打印 ptr 的地址 ptr += 1; // 将指针的值加一 printf("ptr 指向地址为 %p 的内存\n", ptr); // 打印 ptr 的地址 return 0; }

说明:

  • ptr += 1 将指针的地址加一
    • ptr 的值实际增加量不是 1 而是 4, 因为 ptrint 类型的指针,因此地址量增加为 int 类型的字节数

运行结果:

ptr 指向地址为 0x4 的内存 ptr 指向地址为 0x8 的内存

#指向指针的指针

指针中保存的内存地址也可以是另一个指针,例如 int** 指向 int*

示例:

#include <stdio.h> int main(void) { int x = 2333; // 定义整型变量 x int* ptr = &x; // 定义整型指针 ptr,它的初始值为变量 x 的地址 int** ptr_to_ptr = &ptr; // 定义整型指针的指针 ptr_ptr,它的初始值为变量 ptr 的地址 printf("ptr_to_ptr 指向地址为 %p 的内存\n", ptr_to_ptr); // 通过 %p 打印指针本身 printf("ptr 指向地址为 %p 的内存\n", *ptr_to_ptr); // *ptr_to_ptr 取值,因为 ptr_to_ptr 的类型是 int** 因此按照 int* 类型进行取值 printf("x 的值为 %d\n", **ptr_to_ptr); // **ptr_to_ptr 取值,因为 *ptr_to_ptr 的类型是 int* 因此按照 int 类型进行取值 return 0; }

说明:

  • ptr 指向 x
  • ptr_to_ptr 指向 ptr

内存

变量:x
值:2333

ptr

ptr_to_ptr

运行结果:

ptr_to_ptr 指向地址为 0x7ffcf0bbc558 的内存 ptr 指向地址为 0x7ffcf0bbc554 的内存 x 的值为 2333

Anya 的指针示意图.png

#NULL

C 语言中使用 NULL 表示无效的指针,它的值是 0。

int* ptr = NULL; // 初始值设为 NULL

#void*

C 语言中使用 void* 表示泛型指针(任意类型的指针),提供灵活的内存操作和数据类型抽象,尤其在底层编程、内存管理和跨类型数据传递中非常关键。

它不能进行计算和解引用,必须转换成特定类型的指针才能解引用。

int x = 10; void* ptr = (void*)&x; int* ptr2 = (int*)ptr;

#同时定义多个指针时的陷阱

不可用下面这段代码的方式定义多个指针:

int* x, y;
  • x 的类型是 int*
  • y 的类型是 int

这是 C 语言的设计缺陷,容易导致误解。

正确的写法是:

int *x, *y;
  • x 的类型是 int*
  • y 的类型是 int*

创建于 2025/6/30

更新于 2025/6/30