这是我们旧的C++考试中的一个问题.这段代码让我发疯,任何人都可以解释它的作用 - 特别是 - 为什么?
int arr[3]={10,20,30};
int *arrp = new int;
(*(arr+1)+=3)+=5;
(arrp=&arr[0])++;
std::cout<<*arrp;
Run Code Online (Sandbox Code Playgroud)
CB *_*ley 13
此语句*(arr+1)两次写入对象而没有插入序列点,因此具有未定义的行为.
(*(arr+1)+=3)+=5;
Run Code Online (Sandbox Code Playgroud)
此语句arrp两次写入对象而没有插入序列点,因此具有未定义的行为.
(arrp=&arr[0])++;
Run Code Online (Sandbox Code Playgroud)
代码可能会导致任何事情发生.
参考:ISO/IEC 14882:2003 5 [expr]/4:"在前一个和下一个序列点之间,标量对象的表达式评估最多只能对其存储值进行一次修改."
(*(arr+1)+=3)+=5;
Run Code Online (Sandbox Code Playgroud)
arr + 1 - 索引为1
*(arr + 1)的元素 - 此元素的值
(arr + 1)+ = 3 - 增加3
((arr + 1)+ = 3)+ = 5 - 增加5;
所以arr [1] == 28
(arrp=&arr[0])++;
Run Code Online (Sandbox Code Playgroud)
arr [0] - 元素0的值
&arr [0] - 元素0的地址
arrp =&arr [0] - 将arrp设置为指向elem 0
(arrp =&arr [0])++ - 将arr设置为指向elem 1
结果:28
这一行:
(*(arr+1)+=3)+=5;
Run Code Online (Sandbox Code Playgroud)
产生与此相同的结果(见脚注):
arr[1] += 3;
arr[1] += 5;
Run Code Online (Sandbox Code Playgroud)
这一行:
(arrp=&arr[0])++;
Run Code Online (Sandbox Code Playgroud)
产生与此相同的结果(见脚注):
int* arrp = arr+1;
Run Code Online (Sandbox Code Playgroud)
所以这一行:
std::cout<<*arrp
Run Code Online (Sandbox Code Playgroud)
打印出来28.
但是这段代码会泄漏内存,因为在堆上int *arrp = new int;分配一个新int的,它将在赋值时丢失(arrp=&arr[0])++;
脚注:当然我假设没有古怪.
编辑:由于C++ Standard 5/4,显然有些行实际上会导致未定义的行为.所以这真是一个糟糕的考试问题.