This was a question in our old C++ exam. This code is driving me crazy, could anyone explain what it does and - especially - why?
int arr[3]={10,20,30};
int *arrp = new int;
(*(arr+1)+=3)+=5;
(arrp=&a开发者_开发知识库mp;arr[0])++;
std::cout<<*arrp;
This statement writes to the object *(arr+1) twice without an intervening sequence point so has undefined behavior.
(*(arr+1)+=3)+=5;
This statement writes to the object arrp twice without an intervening sequence point so has undefined behavior.
(arrp=&arr[0])++;
The code could result in anything happening.
Reference: ISO/IEC 14882:2003 5 [expr]/4: "Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression."
(*(arr+1)+=3)+=5;
arr + 1 - element with index 1
*(arr + 1) - value of this element
(arr + 1) += 3 - increase by 3
((arr+1)+=3)+=5 - increase by 5;
so arr[1] == 28
(arrp=&arr[0])++;
arr[0] - value of element 0
&arr[0] - address of element 0
arrp=&arr[0] - setting arrp to point to elem 0
(arrp=&arr[0])++ - set arr to point to elem 1
result: 28
This line:
(*(arr+1)+=3)+=5;
produces the same result as this (see footnote):
arr[1] += 3;
arr[1] += 5;
This line:
(arrp=&arr[0])++;
produces the same result as this (see footnote):
int* arrp = arr+1;
So this line:
std::cout<<*arrp
prints out 28.
But this code leaks memory because int *arrp = new int; allocates a new int on the heap which will be lost on assignment by (arrp=&arr[0])++;
Footnote: Of course I'm assuming an absence of weirdness.
Edit: Apparently some of the lines in fact lead to undefined behavior, due to C++ Standard 5/4. So this really is a crappy exam question.
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) is the same as arr[1], which means that *(arr+1)+=3 will increase arr[1] by 3, so arr[1] == 23 now.
(*(arr+1)+=3)+=5 means arr[1] is increased by another 5, so it will be 28 now.
(2)
arrp will pont to the address of the first element of arr (arr[0]). The pointer arrp will then be incremented, thus it will point to the second element after the entire statement is executed.
(3)
Prints what arrp points to: the second element of arr, meaning 28.
Well, remember that arrays can be interpreted as pointers
int arr[3]={10,20,30};
int *arrp = new int;
creates an array arr of three integers and an int pointer that gets assigned with a freshly allocated value.
Since assignment operators return a reference to the value that has been assigned in order to allow multi-assignment,
(*(arr+1)+=3)+=5;
is equivalent to
*(arr+1)+=3;
*(arr+1)+=5;
*(arr + 1) refers to the first element of the array arr, therefore arr[1] is effectively increased by eight.
(arrp=&arr[0])++; assigns the address of the first array element to arrp and afterward increments this pointer which now points to the second element (arr[1] again).
By dereferencing it in std::cout<<*arrp, you output arr[1] which now holds the value 20 + 3 + 5 = 28.
So the code prints 28 (and furthermore creates a memory-leak since the new int initially assigned to arrp never gets deleted)
I'll try to answer you by rewriting the code in a simpler way.
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]
I am assuming you understand pointers and basic c.
加载中,请稍侯......
精彩评论