c语言10:指针加减指针的那些事儿
在 C 语言中,指针是一个强大而又容易让人迷惑的特性。特别是指针之间的运算,常常让初学者感到头疼。今天我们就来深入探讨一个具体问题:指针之间的加减运算到底有哪些规则和注意事项
指针减指针:合法且有用
首先明确一点:两个指针之间是可以进行减法运算的,但这有严格的前提条件
指针减法的前提条件:
- 两个指针必须是同类型的
- 两个指针必须指向同一个数组中的元素(或者数组最后一个元素的下一个位置)
指针减法的结果
两个指针相减的结果并不是简单的地址差值(字节数),而是两个指针之间的元素个数。这个结果的类型是ptrdiff_t
(在<stddef.h>
中定义的一种有符号整数类型)。
实际实例:
#include <stdio.h>
#include <stddef.h>int main()
{int arr[] = {10, 20, 30, 40, 50, 60};int *p_start = &arr[0]; // 指向数组第一个元素int *p_mid = &arr[2]; // 指向数组第三个元素int *p_end = &arr[5]; // 指向数组最后一个元素ptrdiff_t diff1 = p_mid - p_start;ptrdiff_t diff2 = p_end - p_mid;ptrdiff_t diff3 = p_end - p_start;printf("p_mid 与 p_start 之间的元素个数: %td\n", diff1); // 输出 2printf("p_end 与 p_mid 之间的元素个数: %td\n", diff2); // 输出 3printf("p_end 与 p_start 之间的元素个数: %td\n", diff3); // 输出 5return 0;
}
指针减法的应用场景:
指针减法在实际编程中有不少用途:
- 计算数组中元素的索引位置
- 判断两个指针的相对位置
- 在处理动态分配的内存块时确定元素边界
- 实现一些数据结构操作(如链表长度计算)
指针加指针:非法且无意义
指针减法不同,两个指针相加在 C 语言中是完全不允许的,会直接导致编译错误。
为什么指针不能相加?
从逻辑上讲,两个内存地址相加没有任何实际意义。
假设我们有两个指针p1
和p2
,它们分别指向内存中的两个位置,p1 + p2
的结果会是什么?这个结果既不指向p1
附近的位置,也不指向p2
附近的位置,更不指向它们之间的某个位置。
简单来说,指针相加的结果是一个没有逻辑意义的地址,因此 C 语言标准明确禁止这种操作。
错误示例:
#include <stdio.h>int main()
{int arr[] = {10, 20, 30};int *p1 = &arr[0];int *p2 = &arr[1];// 下面这行代码会导致编译错误int *p3 = p1 + p2; // 错误:指针不能相加return 0;
}
编译这段代码时,编译器会给出类似 "invalid operands to binary + (have 'int *' and 'int *')" 的错误信息。
指针与整数的加减:常用操作
虽然指针之间不能相加,但指针与整数之间的加减是 C 语言中非常常见且有用的操作
#include <stdio.h>int main()
{int arr[] = {10, 20, 30, 40, 50};int *p = &arr[0]; // 指向第一个元素p++; // 指向arr[1](20)printf("%d\n", *p); // 输出20p += 2; // 指向arr[3](40)printf("%d\n", *p); // 输出40p -= 1; // 指向arr[2](30)printf("%d\n", *p); // 输出30return 0;
}
需要注意的是,指针加上或减去一个整数n
,实际移动的字节数是n * sizeof(指针所指向的类型)
。这就是为什么我们说指针运算具有 "类型感知" 的特性。
总结:
关于 C 语言中指针的加减运算,我们可以得出以下结论:
- 同类型指针可以相减,结果是它们之间的元素个数(类型为
ptrdiff_t
) - 指针之间不能相加,这是非法操作
- 指针可以与整数加减,表示移动指定数量的元素位置
- 进行指针运算时,必须确保指针指向同一个数组(或其末尾),否则行为未定义
掌握指针运算的规则,不仅能帮助我们写出更高效的代码,也能避免许多难以调试的错误。指针是 C 语言的灵魂,深入理解指针运算,是成为 C 语言高手的必经之路。