Here is the code I'm running:
#include <iostream>
using namespace std;
int main()
{
int x = 5;
int *p;
p = &x;
*p++;
cout<<x<<endl;
return 0;
}
The output should be 6, because p is pointing at the address of x. However, I get 5.
But more interestingly, I couldn't understand why the output is 6 when I change *p++ with *p = *p+1. Why is this?
You are wrong. *p++ reads the value that p points to, then increases the pointer p. You probably wanted (*p)++.
*p = *p + 1 works because it is correct.
Postfix ++ has higher precedence than unary *, so *p++ is parsed as *(p++); IOW, you're incrementing the pointer, not the thing being pointed to.
Use (*p)++ to increment the thing being pointed to, or use ++*p.
Use brackets if you do not understand operator precedence.
*p++
is
*(p++)
and you want
(*p)++
The rule of thumb is:
multiplication and division go before addition and subtraction
for everything else, just use brackets
Related
Program 1:
#include <iostream>
using namespace std;
int main(){
int x=5;
int* xd=&x;
cout<<*xd<<endl;
(*xd)++;
cout<<*xd;
}
output is 5 and 6 .
Program 2:
#include<iostream>
using namespace std;
int main(){
int x=5;
int* xd=&x;
cout<<*xd<<endl;
*xd++;
cout<<*xd;
}
Output is 5 and some random number rather than 6.
The second code uses *xd++; which is equivalent to *(xd++); due to operator precedence. In other words, the postfix operator++ has higher precedence than operator * used for indirection and thus by writing *xd++ you're incrementing the pointer xd and then dereferencing that incremented pointer in the next statement cout<<*xd; which leads to undefined behavior.
cout<<*xd;//undefined behavior as this dereferences the incremented pointer
While the first code is well-formed because in code 1, you're first dereferencing the pointer xd and then incrementing that result(which is an int) which is totally fine.
(*xd)++; //valid as you've surrounded xd with parenthesis () and thus you're incrementing x instead of xd
cout<<*xd;//valid as `xd` still points to `x`
For the first lines of code you wrote :
int main(){
int x=5; // Here x is equal to 5
int* xd=&x; // You declare a pointer xd that points on the value of x
cout<<*xd<<endl; // The value of xd is 5.
(*xd)++; // The value of 5 +1 which is equal to 6
cout<<*xd; // Print out 6
As for the second code
include using namespace std;
int main(){
int x=5; // Here x is equal to 5
int* xd=&x; // You declare a pointer xd that points on the value of x
cout<<*xd<<endl; // The value of xd is 5.
*xd++; // increment the value of the pointer address by 1
cout<<*xd; // Display a random pointer address
}
To understand more, you should learn about the pointer address and the pointer value
Doing (*xd)++ will increment the value of your pointer.
As for *xd ++ will increment a random value that your pointer address is pointing on.
In the first example, the increment operator is being performed on the dereferenced value of xd (i.e. 5+1).
In the second example, the incprement operator is being performed on the pointer to the memory address where 5 is held, i.e. moving the pointer to after the value (which is not initialized)
I've Got the right answer to that Question.
Actually some operators have the same precedence, like '*' and '++'. So if they're found in the same statement the compiler deals them with associativity .
Associativity is concerned with whether the compiler performs operations starting with an operator on the right or an operator on the left.
If a group of operators has right associativity, the compiler performs the operation on the right side of the expression first, then works its way to the left. The unary operators such as * and ++ have right associativity, so the expression from the 2nd code is interpreted as *(xd++), which increments the pointer first, not what it points to. Since I've used parentheses in first code which means to deference the pointer first (*xd) ... then whatever value it holds..... increment it.
THANK YOU !
This question already has answers here:
How to increment a pointer address and pointer's value?
(5 answers)
Closed 2 years ago.
I was writing a code related to referencing in C/C++. I made a pointer and put it into a function that incremented it. In the function, I wrote *ptr++ and tried to increment the value of the integer the pointer was pointing at.
#include <iostream>
using namespace std;
void increment(int *ptr)
{
int &ref = *ptr;
*ptr++; // gets ignored?
ref++;
}
int main()
{
int a = 5;
increment(&a);
cout << a;
return 0;
}
Can anyone please tell me why I can't increment the variable? I have tried incrementing it using +=1, and it works but not by using ++ operator?
++ has higher precedence than *, so *ptr++ is treated as *(ptr++). This increments the pointer, not the number that it points to.
To increment the number, use (*ptr)++.
Your code is:
*ptr++;
Which is equivalent to:
*(ptr++);
Which means pointer is incremented first and then dereferenced. this happens because increment operator ++ has higher precedence than dereferance operator * . So you should use:
(*ptr)++;
Here first pointer is dereferenced then incremented.
Stroustrup C++ 4th Ed Page 197 has the following examples, which result in an incrementing stream of characters printed until null and not "abc". Questions: how is the ++*p being evaluated? ++ and * are the same precedence and evaluation right-to-left, therefore it's my understanding *p is evaluated first, leading to the character p points to, then this character is incremented by ++. Is this understanding correct? Thanks
#include <iostream>
using namespace std;
void fp(char* p)
{
while (*p)
cout << ++*p;
}
void fr2(char& r)
{
char* p = &r;
while (*p)
cout << ++*p;
}
int main(int argc, char *argv[])
{
char s[] = "abc";
char *p = s;
fp(p);
fr2(*p);
return 0;
}
Yes, you are right about the precedence and the associativity. This expression:
++*p;
is parsed as
++(*p);
i.e. first the indirection of p is done, and then the value returned is incremented.
This means that in the while loop:
while (*p)
cout << ++*p;
the pointer p is never actually incremented. This results in an infinite loop where just the value of p[0] is incremented forever.
Here's a demo, which shows the output as a very long sequence of ascii values starting from a. Note that abc is not printed.
By the same reasoning, the expression:
*++p;
is parsed as:
*(++p);
which is fine, since the pointer is incremented first, and then the pointer is dereferenced.
My Code is:
int abdul = 11;
int *ptr = &abdul;
//Problem is here
// *ptr += 1;
// *ptr++;
cout << &*ptr;
cout << "\n" << &abdul;
cout << *ptr;
}
If I use *ptr +=1 it added 1 in abdul location value. But if I use *ptr++ it gives some random value.
When I use *ptr += 1 the output is correct. But using increment or decrement operator value gets wrong. I don't know where the problem is.
Due to operator precedence, *ptr++ is treated as *(ptr++). The pointer is incremented first and then dereferenced. In your case, that causes undefined behavior since ptr points to a single object.
To increment the value of the object that ptr points to, use (*ptr)++ or ++(*ptr).
It's better to be clear about your intention using parenthesis.
Operator precendece. *ptr++ is evaluated as *(ptr++). But you want (*ptr)++ Just add some parantheses to show the compiler what you want.
Due to the Operator Precedense what happens is you increment the address doing ptr++ and then you dereference it by doing *ptr.
what you can do is use prefix increment : ++*ptr
I'm trying to understand how the parentheses affects the precedence in an expression:
int arr[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
auto b = arr;
std::cout << *(++b) << std::endl;
// output : 1
In this code I get the expected output but if I change it to:
std::cout << *(b++) << std::endl;
// output 0
I get 0 as output. Because of the parentheses I though b++ will be evaluated first and then de-referencing will occur. It seems I was wrong, then I removed the parentheses completely and test with *++b and *b++ and get the same results.Does that mean the parentheses don't affect the precedence on this kind of expressions ? And why are the results of this two expressions are equivelant:
*(b + 1)
*(++b)
But it's not the case with *(b++) ?
It does evaluate the b++ first. b++ increments b and returns the previous value of b, before the increment happened. The result of b++ and the value of b afterwards are different. Think of it as (using int instead of int * because a reference-to-pointer makes the signature ugly):
int postfix_increment(int &x) {
int result = x;
x = x + 1;
return result;
}
(Except that using the incremented value before the next sequence point is undefined behavior.)
If you introduce a temporary variable for the result of the parenthesis, to make sure it's evaluated first, it may be easier to see the difference:
int *tmp = b++;
// At this point, b == tmp + 1!
std::cout << *tmp << std::endl;
*(b++) is equivalent to storing the old pointer, incrementing the pointer and dereferencing the old pointer
int* post_increment(int* b)
{
int* old = b;
++b;
return old;
}
It is an instructive exercise to write a thin iterator wrapper around a plain pointer. When writing user-defined iterators, the above post_increment() function is usually written an overloaded operator++(int). The int argument is purely to distinguish it from the pre-increment operator operator++(). In addition, you'd need an overloaded operator*() to dereference an iterator.
*(b+1) works because you do math. Math takes parentheses into account. Only after Math is done, the expression gets evaluated.
*(++b) works because you increment before evaluation (prefix increment).
*(b++) doesn't work because you increment after evaluation (postfix increment).