指针算术是C语言的一项基本特性,使得内存操作灵活,但也潜在危险。
指针算术源于低级语言的特性,旨在直接处理数组和结构化数据。C中的所有指针都“知道”它们指向的类型的大小。
许多开发者错误地认为,将1加到指针上时,地址只会增加1个字节。实际上,增加的量是sizeof(类型)。在处理不同数据类型时,尤其是不同大小的结构体,容易在内存访问时出错。同时,指针算术与void*是不可进行的——这是一个常见错误。
所有指针的算术操作都考虑到对应类型的大小,从而使对数组的操作高效。例如:
#include <stdio.h> int arr[4] = {10, 20, 30, 40}; int *p = arr; printf("%d\n", *(p + 2)); // 输出30
这里的(p + 2)将指针向前移动2 * sizeof(int)个字节,而不仅仅是2个字节。
关键特点:
可以对void指针执行递增/递减操作吗?
不可以,C标准禁止与void进行算术运算。必须先将指针转换为具体类型,例如(char),然后再进行算术运算。
void *vp = arr; char *cp = (char *)vp; cp++;
如果将超过数组大小的值加到指向结构或数组的指针上,会发生什么?
这将导致超出有效内存范围(未定义行为)。C不会检查数组边界——这由程序员负责。
可以直接将两个指针相加吗?
不可以,指针相加是禁止的,且没有意义。仅允许减去属于同一个数组的两个指针。
一位年轻开发者在处理int数组的指针时,以固定字节数移动指针,忘记了类型大小。
优点:
缺点:
一位经验丰富的开发者总是使用(ptr + n)这样的表达式,依赖编译器根据类型大小进行缩放。
优点:
缺点: