帮助我理解这个奇怪的C++代码

jav*_*ava 6 c++

这是我们旧的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:"在前一个和下一个序列点之间,标量对象的表达式评估最多只能对其存储值进行一次修改."


And*_*rey 9

(*(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


In *_*ico 6

这一行:

(*(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,显然有些行实际上会导致未定义的行为.所以这真是一个糟糕的考试问题.

  • @In silico:是的,这就是必须如何评估表达式,但是两个写入是`+ =`的副作用并没有被一个序列点相互分开,所以行为是不确定的,除非你有一个争论为什么不是? (2认同)