Click here to Skip to main content
16,018,664 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I appreciate if someone knowledgeable describes why in the expressions like *p++ the pointer's value changes?
#include <stdio.h>

int main(void) {
    int a=1,*p;
    p=&a;
    printf("The original Addres=%p and a= %d\n",p,a);
    a=(*p)++;
    printf ("The second Address=%p and a=%d",p,a);
}


What I have tried:

even in *p++; the pointer' value is chaned rather than the varianle's value.
Posted
Updated 24-Feb-23 10:31am
v2

In the code you have posted the address of p remains constant.
C++
a = (*p)++;

The reason is that the above statement says:
- take the value stored in p and increment it by one
- then save the resultant value in variable a

*** see latest comments below.
In this case the value of p's address does not change.


If you change the code to:
C++
a = *p++;

then p will increase, but a will not, as this statement says:
- take the value stored in p and copy it into variable a
- then increment the address of p

[edit]
As pointed out by 0x01AA my answer for the first case is incorrect. I have run further tests and it appears that the Microsoft compiler may have a bug as it incorrectly stores the incremented value of the variable. I have double checked with the assembler output and the generated code is definitely wrong.
I will raise a bug report with Microsoft.
[edit]
 
Share this answer
 
v2
Comments
0x01AA 24-Feb-23 13:55pm    
Not really correct and no vote from my side! a = (*p)++; means
assign the value stored in p and afterwards increment the value stored on p.... and that increment disapears then in the nirvana ;)
Richard MacCutchan 25-Feb-23 3:48am    
I am not sure I understand what you are saying, but my answer is based on running both versions of the code, and hence is correct.
0x01AA 25-Feb-23 11:46am    
I'm only on the first case a = (*p)++;

You wrote
- take the value stored in p and increment it by one
- then save the resultant value in variable a

But it is, because post increment
- take the value stored in p and assign it to a
- then increment the value (*p), which at least with my compiler does nothing.

Not a thing to worry about I think ;)
Richard MacCutchan 26-Feb-23 3:17am    
You are correct, but only partly. If I run this code in a pure C program I get the following result:
The original Addres=000000E21EDFF774 and a= 1
The second Address=000000E21EDFF774 and a=2

But if I run it in a C++ program I get a different (correct?) result:
The original Addres=0000007B1A2FFC84 and a= 1
The second Address=0000007B1A2FFC84 and a=1

So it looks like C code treats that expression differently. I will have to dust off my K&R to see why.
0x01AA 26-Feb-23 5:07am    
Thank you very much for your feedback.
I tested it indeed with c++. So have my 5 then.
The following piece of code, similar to your program:
C
#include <stdio.h>

int main()
{
    int a=1,*p;
    p=&a; // here 'p' points to 'a', that is 'p' contains the address of 'a'

    printf("p = %p, a = %d \n", p, a);

    a=(*p)++; // this means: take the value pointed by p, assign it to a, and eventually increment it.
              // i.e. equivalent to the sequence:
              //   a = a;
              //   (a+1);
              // having no effect.

    printf("then\np = %p, a = %d \n", p, a);

    return 0;
}
produces on my system:
p = 0x7ffe47db05bc, a = 1 
then
p = 0x7ffe47db05bc, a = 1 
(No changes)


While this one
C
#include <stdio.h>

int main()
{
    int a=1,*p;
    p=&a; // here 'p' points to 'a', that is 'p' contains the address of 'a'

    printf("p = %p, a = %d \n", p, a);

    a=*p++; // this means: take the value pointed by p, assign it to a, and eventually increment p.
              // i.e. equivalent to the sequence:
              //   a = a;
              //   p = &a + sizeof(a)
              //
    printf("then\np = %p, a = %d \n", p, a);

    return 0;
}
produces
p = 0x7fff71b6233c, a = 1 
then
p = 0x7fff71b62340, a = 1 
(the value of p changed)

Finally, this one
C
#include <stdio.h>

int main()
{
    int a=1,*p;
    p=&a; // here 'p' points to 'a', that is 'p' contains the address of 'a'

    printf("p = %p, a = %d \n", p, a);

    a=++(*p); // this means: take the value pointed by p, increment it, assign it to a.
              // i.e. equivalent to the statement:
              //   a = a + 1;

    printf("then\np = %p, a = %d \n", p, a);

    return 0;
}
produces
p = 0x7ffee94b2e2c, a = 1 
then
p = 0x7ffee94b2e2c, a = 2 
(the value of a changed)
 
Share this answer
 
Comments
0x01AA 24-Feb-23 14:17pm    
The correct answer. 5, even pre inc. I don't see in the Question and will most probably confuse OP to mention it :-)
CPallini 24-Feb-23 15:59pm    
The pre increment example is in place because it possibly accomplishes what the user meant to do (if I got him).
BTW, thank you very much.
Ehsan Nazeri 24-Feb-23 16:46pm    
Thank you. I added two variables b and j and encountered weird results.
I wonder why in b=(*p)++ this occurs:
1)b=*p;
2)*p++ that is a=a+1;
but the command a=(*p)++ becomes
1)a=*p;
2)a+1;(without any assigning)
and even stranger why j becomes 8(!) rather than 2.
int main(void) {
int a=1,b,*p,j=1;
p=&a;
printf("The original Addres=:%p and a=%d\n",p,a);
b=(*p)++;
j=j++;
printf ("The second Address=%p and a=%d and b=%d and j=%d",p,a,b);
}
Richard MacCutchan 25-Feb-23 3:51am    
In your final print statement:
printf ("The second Address=%p and a=%d and b=%d and j=%d",p,a,b);

You forgot to pass the variable j in the parameter list, so the value printed is from some random address.
Ehsan Nazeri 3-Mar-23 14:49pm    
Thanks. I have two questions. 1) How about b=(*a)++; ? why it works correctly but a=(*a)++; doesn't?
2) if the precedence of = is the lowest precedence (?) why doesn't the compiler implement the ++ before the = operator?
There's two things going on here. The first is operator precedence, and the second is postincrement.
C
 // the expression:
a = *p++;
// is equivalent to
a = *p;  // dereference p 
p += 1;  // increment p after access
         // Note that now dereferncing p invokes undefined behavior

// If you want to increment what p is pointing to without moving it then you want
a = ++(*p);
// Note that as the source and destination are the same address, I think it is undefined as
// to what gets assigned to a.  It's much better in this case to do
a = *p + 1;
// as that will not invoke undefined behavior.
 
Share this answer
 
Comments
0x01AA 24-Feb-23 14:03pm    
The question was about a=(*p)++; and not a = *p++; which is a different thing ;)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900