1. 指针运算的合法性解析
在C++编程中,指针运算是一把双刃剑。它既能提供高效的内存访问能力,又可能成为程序崩溃的隐患。理解指针运算的合法性边界,是每个C++开发者必须掌握的核心技能。
1.1 指针运算的基本前提
指针运算的合法性首先取决于指针所指向的内存类型。只有指向数组或连续内存块的指针才能进行合法的算术运算。这个原则看似简单,但在实际编程中却经常被忽视。
关键点:指针运算的合法前提是指针必须指向数组或连续分配的内存块。这包括栈数组、new[]分配的堆数组以及malloc分配的连续内存。
让我们看一个典型示例:
cpp复制int arr[5] = {1, 2, 3, 4, 5};
int* p = arr; // 合法:指向数组首元素
p++; // 合法:移动到arr[1]
1.2 合法的指针运算类型
在满足前提条件的情况下,C++允许以下几种指针运算:
1.2.1 指针与整数的加减运算
指针加减整数的运算实际上是在移动指针的位置。移动的步长由指针类型决定:
cpp复制double arr[5] = {1.1, 2.2, 3.3, 4.4, 5.5};
double* p = arr;
p += 2; // 移动2个double位置,即16字节(假设double为8字节)
1.2.2 指针间的减法运算
指针减法运算的结果是两个指针之间的元素个数差,而不是字节差:
cpp复制int arr[5] = {0};
int* p1 = arr;
int* p2 = arr + 3;
ptrdiff_t diff = p2 - p1; // 结果为3,不是12(字节)
1.2.3 指针的比较运算
指针比较运算可以判断两个指针在内存中的相对位置:
cpp复制int arr[5] = {0};
int* p1 = arr;
int* p2 = arr + 2;
bool b = p1 < p2; // true
1.3 非法的指针运算
以下是指针运算中常见的非法操作,它们都属于未定义行为:
1.3.1 单个变量的指针运算
cpp复制int a = 10;
int* p = &a;
p++;
