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

时间:2010-06-06 17:59:52

标签: c++

这是我们旧的C ++考试中的一个问题。这段代码让我发疯,有人能解释它的作用吗 - 特别是 - 为什么?

int arr[3]={10,20,30};
int *arrp = new int;

(*(arr+1)+=3)+=5;
(arrp=&arr[0])++;

std::cout<<*arrp;

6 个答案:

答案 0 :(得分:13)

此语句在没有插入序列点的情况下两次写入对象*(arr+1),因此未定义行为

(*(arr+1)+=3)+=5;

此语句在没有插入序列点的情况下两次写入对象arrp,因此未定义行为

(arrp=&arr[0])++;

代码可能会导致任何事情发生。

参考:ISO / IEC 14882:2003 5 [expr] / 4:“在前一个和下一个序列点之间,标量对象的表达式评估最多只能修改一次存储值。”

答案 1 :(得分:9)

(*(arr+1)+=3)+=5;

arr + 1 - 索引为1的元素 *(arr + 1) - 此元素的值
(arr + 1)+ = 3 - 增加3
(arr + 1)+ = 3)+ = 5 - 增加5;

所以arr [1] == 28

(arrp=&arr[0])++;

arr [0] - 元素0的值
&amp; arr [0] - 元素0的地址 arrp =&amp; arr [0] - 将arrp设置为指向elem 0
(arrp =&amp; arr [0])++ - 将arr设为指向elem 1

结果:28

答案 2 :(得分:6)

这一行:

(*(arr+1)+=3)+=5; 

产生与此相同的结果(见脚注):

arr[1] += 3;
arr[1] += 5;

这一行:

(arrp=&arr[0])++;   

产生与此相同的结果(见脚注):

int* arrp = arr+1;

所以这一行:

std::cout<<*arrp

打印出28

但是这段代码会泄漏内存,因为int *arrp = new int;会在堆上分配一个新的int(arrp=&arr[0])++;

会在分配时丢失

脚注:我当然假设没有古怪。

编辑:由于C ++ Standard 5/4,显然有些行实际上会导致未定义的行为。所以这真是一个糟糕的考试问题。

答案 3 :(得分:1)

int arr[3]={10,20,30}; // obvious?
int *arrp = new int; // allocated memory for an int

(*(arr+1)+=3)+=5; // (1)
(arrp=&arr[0])++; // (2)

std::cout<<*arrp; // (3)

<强>(1)

*(arr+1)arr[1]相同,这意味着*(arr+1)+=3会将arr[1]增加3,所以现在arr[1] == 23

(*(arr+1)+=3)+=5表示arr[1]增加了5,因此现在为28

<强>(2)

arrp将指向arrarr[0])的第一个元素的地址。然后指针arrp将递增,因此它将在执行整个语句后指向第二个元素。

<强>(3)

打印arrp指向的内容:arr的第二个元素,意为28

答案 4 :(得分:0)

好吧,请记住,数组可以解释为指针

int arr[3]={10,20,30};
int *arrp = new int;

创建一个包含三个整数的数组arr和一个int pointer,并为其分配一个新分配的值。

由于赋值运算符返回对已分配的值的引用以允许多重赋值,

(*(arr+1)+=3)+=5;

相当于

*(arr+1)+=3;
*(arr+1)+=5;

*(arr + 1)是指数组arr的第一个元素,因此arr[1]实际上会增加8个。

(arrp=&arr[0])++;将第一个数组元素的地址分配给arrp,然后递增此指针,该指针现在再指向第二个元素(arr[1])。

通过在std::cout<<*arrp中解除引用,您输出的arr[1]现在保留了值20 + 3 + 5 = 28

因此代码打印28(并且由于最初分配给new int的{​​{1}}永远不会获得arrp d),因此会产生内存泄漏

答案 5 :(得分:0)

我会尝试以更简单的方式重写代码来回答你。

int arr[3]={10,20,30};
int *arrp = new int;

(*(arr+1)+=3)+=5;
(arrp=&arr[0])++;

std::cout<<*arrp;

=== equals ===

int arr[3]={10,20,30};//create array of 3 elements and assign them
int *arrp = new int;//create an integer pointer and allocate an int to it(useless)

//(*(arr+1)+=3)+=5;
arr[1] = arr[1] + 3;//arr[1] == arr+1 because it is incrementing the arr[0] pointer
arr[1] = arr[1] + 5;

//(arrp=&arr[0])++;
arrp = &arr[0];//point the integer pointer to the first element in arr[]
arrp++;//increment the array pointer, so this really is now pointing to arr[1]

std::cout<<*arrp;//just print out the value, which is arr[1]

我假设您理解指针和基本c。