指针加减整数指针可以加减整数结果按元素大小缩放不是按字节int arr[5] {10, 20, 30, 40, 50}; int *p arr; p 1 // 指向 arr[1]地址加 4 字节sizeof(int) p 3 // 指向 arr[3]地址加 12 字节 p - 1 // 指向 arr[-1]越界未定义行为p和p--也常用int *p arr; p; // p 从 arr[0] 移到 arr[1] p--; // p 从 arr[1] 移回 arr[0]为什么按元素缩放这是 C 语言的设计选择。如果p 1是加 1 字节那遍历数组时你得自己算p sizeof(int)——繁琐且容易出错。按元素缩放让你可以直接p跳到下一个元素。指针相减两个指向同一数组的指针可以相减结果是元素个数int arr[5] {10, 20, 30, 40, 50}; int *p1 arr[1]; int *p2 arr[4]; printf(%td\n, p2 - p1); // 3间隔 3 个元素注意结果是元素个数3不是字节数12。限制只能对同一数组的指针做。不同数组的指针相减是未定义行为。指针比较同一数组的指针可以比较大小int arr[5]; int *p arr[1]; int *q arr[3]; if (p q) printf(p 在 q 前面\n); // arr[1] 地址更小 if (p q) printf(相同\n); if (p ! q) printf(不同\n);同样只对同一数组有意义。下标的另一种写法int arr[5] {10, 20, 30, 40, 50}; int *p arr; // 以下全部等价 p[3] // 40 *(p 3) // 40 3[p] // 40合法但别这么写3[p]为什么合法编译器将a[b]解析为*(a b)加法交换律*(3 p)和*(p 3)一样。语法上合法风格上禁止——写了会被同事打。函数指针函数也有地址可以用指针存储int add(int a, int b) { return a b; } int (*fp)(int, int) add; // fp 是函数指针 int result fp(3, 4); // 通过指针调用结果 7声明语法返回类型 (*指针名)(参数类型列表)void (*callback)(int); // 指向 void func(int) 的指针 int (*compare)(const void*, const void*); // 指向比较函数的指针实际用途回调函数函数指针最常见的用途是回调——把一个函数传给另一个函数// 排序时传入比较函数 int cmp(const void *a, const void *b) { return *(int*)a - *(int*)b; } int arr[] {3, 1, 4, 1, 5}; qsort(arr, 5, sizeof(int), cmp); // cmp 就是回调函数qsort不知道你要怎么排序你通过函数指针告诉它。指针数组指针数组数组的每个元素是指针。int a 1, b 2, c 3; int *arr[3] {a, b, c}; // 3 个 int* 指针 printf(%d\n, *arr[0]); // 1 printf(%d\n, *arr[1]); // 2最常见用途存储多个字符串char *names[] {Alice, Bob, Charlie}; printf(%s\n, names[0]); // Alice printf(%s\n, names[1]); // Bob每个char *指向一个字符串常量。比二维数组灵活——字符串长度可以不同。main 的命令行参数int main(int argc, char *argv[]) { // argc: 参数个数 // argv: 指针数组每个元素是一个字符串 for (int i 0; i argc; i) { printf(%s\n, argv[i]); } return 0; }运行./program hello world./program hello world指针数组 vs 数组指针int *p[5]; // 指针数组5 个 int* 组成的数组 int (*p)[5]; // 数组指针指向含 5 个 int 的数组的指针判断方法[]优先级高于*看*先跟谁结合。*p[5]p先跟[5]数组再跟*指针→ 指针数组(*p)[5]括号让*先跟p指针再跟[5]数组→ 数组指针常见误区速查误区正确理解p 1加 1 字节加 1 个元素大小指针相减得字节数得元素个数不同数组指针可以相减未定义行为3[p]是语法错误合法但别用函数指针很少用回调函数、qsort 等场景常见总结指针加减整数按元素大小缩放指针相减结果是元素个数只对同数组有效p[3]≡*(p3)≡3[p]最后一种别用函数指针存函数地址常见于回调函数指针数组常见于存储多个字符串和命令行参数指针数组int *p[5]和数组指针int (*p)[5]不同