这是我们旧的C ++考试中的一个问题。这段代码让我发疯,有人能解释它的作用吗 - 特别是 - 为什么?
int arr[3]={10,20,30};
int *arrp = new int;
(*(arr+1)+=3)+=5;
(arrp=&arr[0])++;
std::cout<<*arrp;
答案 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
将指向arr
(arr[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。