Pointers on C 阅读笔记

摘要值得注意的内容。

指针类型和声明

int *a 声明指向 int 的指针 a ,即 *a 的类型是 int 让将 25 赋值给地址为 100 的位置:

1
2
*100 = 25 // wrong. 100 类型为 int, * 运算符只能作用于指针类型的表达式上
*(int *)100 = 25 // right

指向指针的指针:

1
2
3
4
int a = 12;
int *b = &a;
int **c = &b; // declare that **c is of type int

不允许声明指向字面量的指针,原因: 字面量仅存在于编译环节,用于表达式、赋值、初始化,不存储于内存空间。(某些场合会被初始化为此字面量的临时变量代替)

指针运算

p += a: p 的地址增加 sizeof(*p)

*cp ++ 的过程: 因为 ++ 的优先级高于 *~,所以执行过程如下: 1. ~++ 制造一份 cp 的拷贝

  1. ++ 使 cp += 1
  2. * 作用于返回的拷贝

~p1 - p2~: 仅当 p1 和 p2 在同一个数组内有效,等价于 i - j,其中 *p1 = array[i]*p2 = array[j]

多维数组

多维数组实际按顺序「一维」地储存在内存中。

考虑多维数组时,应该将其视为一个由复合元素组成的数组。下面以二维数组为例具体说明:

1
2
3
4
5
int matrix [3][8];
matrix // int ** 指向一个由 int[8] 组成的数组的开头(指向二维数组的第一行)
matrix + 1 // int ** 指向一个由 int[8] 组成的数组的开头(指向二维数组的第二行)
*(matrix + 1) // int * 指向 int[8] 的开头(指向二维数组的第二行第一列)
*(*(matrix + 1) + 5) // int matrix[1][5] <=> *(matrix[1] + 5)

多维数组作为参数传入时,第一维以外的维度大小必须声明,如: void f(int mat[][5]) 因为每一维下标在实际内存中的位置都是基于其元素(更高维)的大小上计算出来的。

函数指针

  • int *f() 声明返回 int * 的函数 f ,因为 () 的优先级比 *
  • int (*f)() 声明一个指向返回 int 的函数的函数指针 f
  • int (*f[])() 声明一个由指向返回 int 的函数的函数指针所组成的指针数组 f