Skip to main content

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 时

退化对照表

表达式原始 / 结果类型含义
aint[10]整个数组
aint *大多数表达式中退化后
&aint (*)[10]指向整个数组
a + 0int *指向 a[0]
*p2int[10]整个数组
*p2int *大多数表达式中退化后
&(*p2)int (*)[10]指向整个数组
(*p2) + 0int *指向第一个元素
a[0]int第一个元素
&a[0]int *第一个元素的地址