1. 指针的本质与内存模型
指针是C/C++语言中最强大也最危险的工具之一。理解指针首先要从计算机内存的基本工作原理说起。在32位系统中,每个内存地址对应一个32位(4字节)的存储单元,64位系统则是64位(8字节)地址空间。
当我们声明一个变量时:
c复制int num = 42;
编译器会在内存中分配4个字节(假设int为32位)的空间,并将值42存储其中。指针变量存储的正是这个内存地址。指针的类型(如int*)告诉编译器如何解释该地址处的数据。
指针变量本身也占用内存空间(通常4或8字节),这解释了为什么指针也需要分配和释放。理解这一点对避免内存泄漏至关重要。
关键认知:指针的值是内存地址,指针的类型决定了如何解释该地址处的数据。这是理解所有指针操作的基础。
2. 指针的基础操作解析
2.1 声明与初始化
指针声明遵循"类型* 变量名"的格式:
c复制int* p; // 声明int型指针
char* str; // 声明char型指针
未初始化的指针称为"野指针",指向随机内存地址,极易导致程序崩溃。安全的初始化方式包括:
c复制int* p = NULL; // 显式初始化为空
int x = 10;
int* p = &x; // 指向现有变量
int* p = (int*)malloc(sizeof(int)); // 动态分配
2.2 取地址与解引用
&运算符获取变量地址:
c复制int num = 42;
int* p = # // p现在保存num的地址
*运算符解引用指针,访问指向的内存:
c复制printf("%d", *p); // 输出42
*p = 100; // 修改num的值为100
2.3 指针运算
指针运算基于指向类型的大小自动缩放:
c复制int arr[3] = {1,2,3};
int* p = arr; // 指向数组首元素
p++; // 移动sizeof(int)字节,指向arr[1]
这种特性使得指针成为遍历数组的高效工具,但也容易导致越界访问。
3. 指针与数组的深层关系
数组名在大多数情况
