Pointer in C/C++
基础示例
int a;
a = 10;
int *p;
p = &a;
printf("%d", *p); // output: 10
p 的类型是 int *。
三种声明
int *p1[10]; // 指针数组
int (*p2)[10]; // 数组指针
int a[10]; // 数组
| 声明 | 含义 | 类型 |
|---|---|---|
p1 | 指针数组:由多个指针构成的数组 | int *[10] |
p2 | 数组指针:指向整个数组 | int (*)[10] |
a | 数组 | int [10] |
p1 可以看成类似 Python 的 list:
[int *, int *, int *, int *, ...]
赋值与访问
p2 = &a;
for (int i = 0; i < 10; i++) {
p1[i] = &a[i];
}
(*p2)[0] = 11;
printf("%d", a[0]); // output: 11
神秘的退化(decay)
a 本身的类型是 int [10]。
在大多数表达式中,a 会退化为 int *,并指向第一个元素 &a[0]:
p1[0] = a; // 数组名在表达式右边:int [10] 退化为 int *(即 &a[0])
p1[0] = *p2; // *p2 本是 int [10],在表达式右边退化为 int *(即 &(*p2)[0])
a是一个int[10]数组表达式*p2也是一个int[10]数组表达式
什么时候不退化
sizeof- 取地址
& - C 语言中使用
_Alignof时
退化对照表
| 表达式 | 原始 / 结果类型 | 含义 |
|---|---|---|
a | int[10] | 整个数组 |
a | int * | 大多数表达式中退化后 |
&a | int (*)[10] | 指向整个数组 |
a + 0 | int * | 指向 a[0] |
*p2 | int[10] | 整个数组 |
*p2 | int * | 大多数表达式中退化后 |
&(*p2) | int (*)[10] | 指向整个数组 |
(*p2) + 0 | int * | 指向第一个元素 |
a[0] | int | 第一个元素 |
&a[0] | int * | 第一个元素的地址 |