问题历史: 在 C 语言中,指针是存储其他对象地址的变量。出现了一个问题:如何比较这样的值,因为内存可能以最不可预测的方式分配。语言允许指针之间的比较操作,但施加了一系列限制,以确保行为保持确定性。
问题: 只有相同数组的元素或同一对象的指针之间的比较是正确的。指向不相关对象(不同变量或未包含在同一数组中的分配内存区域)的指针比较是未定义行为(undefined behavior)。
解决方案: 应避免比较指向不相关内存区域的指针,只在同一数组/字符串/缓冲区内使用,并且与 NULL 的比较是安全的。
代码示例:
#include <stdio.h> int main() { int arr[5] = {1, 2, 3, 4, 5}; int *p1 = &arr[1]; int *p2 = &arr[3]; if (p1 < p2) { printf("p1 指向的数组元素早于 p2 指向的元素\n"); } }
关键特点:
1. 可以比较通过 malloc 获取的指针,它们指向不同的内存块吗?
不可以,比较这样的指针是不允许的——标准未定义其行为。仅允许比较指向同一分配内存块的指针或与 NULL。
2. 如果 int 和 double 类型的指针指向不同变量但具有相同的数值,比较返回什么?**
只在两个指针被转换为相同类型并指向同一对象的情况下,比较才是可能的。如果不符合该条件,结果是未定义的——地址值可能相同,但标准并不保证这种行为。
3. 将指向数组第一个元素的指针与指向其结尾的指针(例如,arr 和 arr + N)进行比较是否正确?
是的,这是正确的。arr + N 指向的是 imaginary 元素,位于最后一个元素之后,编译器保证 arr <= arr + N。
一名员工决定实现一个地址比较函数,以确定两种从不同内存块分配的结构"哪个先创建"。
优点:
缺点:
经过审查后,实现了通过将所有结构分配到同一缓冲区并在允许范围内进行比较来检查指针是否属于同一内存块。
优点:
缺点: