#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
处的值
运行结果:
指针指向地址为 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
处的值
运行结果:
指针指向地址为 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, 因为ptr
是int
类型的指针,因此地址量增加为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
运行结果:
ptr_to_ptr 指向地址为 0x7ffcf0bbc558 的内存 ptr 指向地址为 0x7ffcf0bbc554 的内存 x 的值为 2333
#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*