数组

1
2
3
4
5
#include<iostream>
int main() {
int a[] = { 1,2,3 }; int* p = a;
printf("%d %d %d\n", *p, *p++, *++p);
}

上述代码输出是多少:有两种答案。

不同编译器/优化级别/目标平台,可能打印出不同结果,甚至崩溃。你在某些编译器上可能会看到例如:

  • 若从左到右求值:1 1 3
  • 若从右到左求值:3 2 2

C 语言里是“未定义行为(Undefined Behavior, UB)上述就是,这样无法得出唯一输出。

为啥是UB?

C 标准规定:**同一序列点之间多次修改同一标量,或修改且未顺序化的访问,行为未定义**。

如果将代码改为:

1
2
3
printf("%d ", *p);      // 1
printf("%d ", *p++); // 1 ,然后 p->a[1]
printf("%d\n", *++p); // p 先到 a[2] 再取值 => 3

输出就为:1,1,3


数组的其他性质:

1
2
3
4
5
6
7
8
9
10
int a[] = { 1,2,3,4,6,7 };
int* p = a;
auto p1 = &a;
printf("%d ", sizeof(*p));
printf("%d ", sizeof(*(p+1)));
printf("%d\n", sizeof(p+2));
printf("%d\n", sizeof(&a));
printf("%d\n", sizeof(a));
printf("%d ", sizeof(*p1));
printf("%d ", sizeof(p1));

在32位环境输出如下:

sizeof(*p)*p 的类型是 int ⇒ 4

sizeof(*(p+1)):同样解引用为 int ⇒ 4

sizeof(p+2)p+2 的类型是 int* ⇒ 指针大小 4

sizeof(&a)&a 的类型是 int (*)[6](指向整个数组的指针)⇒ 仍是指针大小 4

sizeof(a):此处是真数组,长度 6,每个 int 4 字节 ⇒ 6*4=24

sizeof(*p1):长度 6,每个 int 4 字节 ⇒ 6*4=24

sizeof(p1):指针大小4