What's the difference between *d++ and (*d)++ in C? - c

as in the title, what's the difference because these two seem to get me the same results?

No they are not the same. Assume that d is a pointer to int:
int n = 0;
int* d = &n;
*d++; // d++ then *d, but d++ is applied after the statement.
(*d)++; // == n++, just add one to the place where d points to.
I think there is an example in K&R where we need to copy a c-string to another:
char* first = "hello world!";
char* second = malloc(strlen(first)+1);
....
while(*second++ = *first++)
{
// nothing goes here :)
}
The code is simple, put the character pointed by first into the character pointed by second, then increment both pointers after the expression. Of course when the last character is copied which is '\0', the expression results to false and it stops!

The increment ++ has higher operator precedence than the dereference *, so *d++ increments the pointer d to point to the next location within the array, but the result of ++ is the original pointer d, so *d returns the original element being pointed to. Conversely, (*d)++ just increments the value being pointed to.
Example:
// Case 1
int array[2] = {1, 2};
int *d = &array[0];
int x = *d++;
assert(x == 1 && d == &array[1]); // x gets the first element, d points to the second
// Case 2
int array[2] = {1, 2};
int *d = &array[0];
int x = (*d)++;
assert(x == 1 && d == &array[0] && array[0] == 2);
// array[0] gets incremented, d still points there, but x receives old value

In the official C terminology, these expressions do give you the same results, as they should. In the proper terminology, the "result" of a non-void expression is what that expression evaluates to. Both of your expressions evaluate to the initial value of *d, so not surprisingly, the results are the same.
However, an addition to a "result" every expression in C has zero or more so called "side effects". And side effects of these two expressions are completely different. The first expression increments the value of pointer 'd'. The second expression increments the value of '*d' (the pointed value).

The first increments the pointer, the second increments the value pointed to.
As an experiment, try this:
int main() {
int x = 20;
int *d = &x;
printf("d = %p\n", d);
int z = (*d)++;
printf("z = %d\n", z);
printf("d = %p\n", d);
int y = *d++;
printf("y = %d\n", y);
printf("d = %p\n", d);
}

They do return the same result, but the state change in your program is completely different.
This is easiest to understand if we just expand out the operations.
x = *d++;
// same as
x = *d;
d += 1; // remember that pointers increment by the size of the thing they point to
x = (*d)++;
// same as
x = *d;
*d += 1; // unless *d is also a pointer, this will likely really just add 1

I don't have a compiler handy.
a = (*d)++;
b = (*d);
is a==b? i don't think it is.

Related

Pointing to a local variable

I would like help understanding this code:
void F (int a, int *b)
{
a = 7 ;
*b = a ;
*b = 4 ;
printf("%d, %d\n", a, *b);
b = &a ;
}
int main()
{
int m = 3, n = 5;
F(m, &n) ;
printf("%d, %d\n", m, n) ;
return 0;
}
I am confused why this does not result in unexpected behavior. At the end of the function F, the value of b is 7. But when I return it is clear that nothing after ' b = &a ' impacts the value of n/b.
I thought that pointing to a local variable would result in garbage/unexpected behavior when the scope changed, but that doesn't appear to be the case.
When you call F, you pass the value of m and the address of n.
In F, b is a pointer to n so that when you change the value of *b, the value of n is changed. However, in "b = &a;" you are changing where b points. After that line, b no longer points to n. Instead, it points to a. That line does nothing at all to the variable n back in main(). After that point, if you change the value of *b, you will change the value of *b and its alias, a. It will not change the value of n in main.
At the end of the function F, the value of b is 7
The value of b is not 7; b is set to point to a, which has the value of 7
But when I return it is clear that nothing after b = &a impacts the value of n
Although b is a pointer, it is passed by value. b inside F behaves as if it were a separate, fully independent, local variable. Any modifications to it made inside F are local to F.
In fact, you cannot trigger undefined behavior in main by actions inside F, because main is not receiving any pointers from F. If you want to make undefined behavior, pass a pointer to pointer into F, and assign it to point to a local variable:
void CauseUB(int a, int **b) {
*b = &a;
}
int main() {
int x = 5, *y = &x;
printf("This is OK: %d\n", *y);
CauseUB(x, &y); // Pointer to pointer
printf("This is UB: %d\n", *y);
return 0;
}
Demo.

What's wrong with the pointers

I am learning pointers in C language. I have written a simple code of pointers using. I have no errors, but the program iz freezing in the middle of execution. What could be the reason for that?
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
void main()
{
int i;
int *i2;
i2 = &i;
int z;
int *z2;
z2 = &z;
int b = 0;
int *b2;
b2 = &b;
char ch[250];
//char *ch2;
//ch2 = &ch;
printf("%s\n", " Enter line not longer than 250 characters");
gets_s(ch);
for (*i2 = 0; *i2<10; i2++)
{
if (*i2>4)
{
*z2 = *i2;
*b2++;
break;
}
}
printf("%d%c", *b2, ch[*z2]);
}
A big problem is your for loop:
for (*i2 = 0; *i2<10; i2++)
i2++ increments the value of the pointer (making it point to something other than i), not the thing being pointed to. You need to change that line to
for (*i2 = 0; *i2<10; (*i2)++)
The parentheses around *i2 are necessary, because the postfix ++ operator has higher precedence than the unary * operator. *i2++ would be parsed as *(i2++), which is not what you want.
for (*i2 = 0; *i2<10; i2++)
should be
for (*i2 = 0; *i2<10; (*i2)++)
NOTE:
Use the standard definition of main()
int main(void) //if no command line arguments.
You asked a second question when you edited your original question (that edit has now been reversed so the actual question has disappeared).
Basically you asked why the printf statement was not returning the expected value.
At that time you had this code:
for (*i2 = 0; *i2<10; (*i2)++)
{
if (*i2>4)
{
*z2 = *i2;
*b2++;
break;
}
}
printf("%d%c\n", b2, ch[z]);
b2 is a pointer ... int *b2;
Now you assign a value to b2 ... b2 = &b;
So now b2 contains the address b and your printf statement prints this address (albeit in integer format '%d' rather than as a pointer %p)
To get the value held in 'b' which is 'pointed to by 'b2', you need to dereference ... *b2
But ... note that you have changed the pointer *b2 with this statement ... *b2++
That statement changed the value of the pointer, not the value of b which it originally pointed to and now *b2 will be undefined.
Change *b2++ to (*b2)++ and change printf b2 to printf *b2
and the result is b + 1 which will be 1 as b was originally set to 0.

Pass by value and pointers

Can you explain why the output is 3?
I was trying to trace the answer and it shows that the line
i+=(a==b?1:0)
gives 1, but doesn't fun1() pass by value so q and p were copied to different variables?
int fun1(int* a, int* b)
{
int i = 0;
i += (&a == &b ? 1 : 0);
i += (a == b ? 1 : 0);
i += (*a == *b ? 1 : 0);
return i;
}
int fun2(int** a, int* b)
{
int i = 0;
i += (a == &b ? 1 : 0);
i += (*a == b ? 1 : 0);
return i;
}
int main(void)
{
int i = 0;
int* p = &i;
int* q = &i;
printf("%d\n", fun1(p, q) + fun2(&p, q));
return 0;
}
In fun1:
(&a==&b?1:0)
This gives 0. They are two different arguments to fun1, basically two different local variables, so they cannot have the same address.
(a==b?1:0)
This gives 1. The values are both &i from main.
(*a==*b?1:0)
This gives 1. Since a and b are equal, they point to the same thing.
In fun2:
(a==&b?1:0)
This gives 0. a and b are both arguments, so a can't equal the address of b (and in fact, it equals &p from main).
(*a==b?1:0)
This gives 1. a is equal to &p from main, so *a is equal to p from main, which is &i from main. And b is equal to q from main, which is again &i from main.
The total is therefore 3.
int fun1(int *a, int*b)
{
int i=0;
i+=(&a==&b?1:0); // 0. &a is the memory where a stands. it's different from &b.
i+=(a==b?1:0); // 1. Both pointers point to the same memory.
i+=(*a==*b?1:0); // 1. *a is the value where it points to, and that's the same as *b.
return i; // returns 2
}
int fun2(int **a, int*b)
{
int i=0;
i+=(a==&b?1:0); // 0
i+=(*a==b?1:0); // 1. *a is the value where it points to, and this is a memory value that is the same as b.
return i; // returns 1
}
That's why it returns 3.
Good question, by the way.
a==b is actually testing whether a and b points to same memory location or not. In function fun1, both a and b points to the same memory location and therefore a==b comes out to be true.
Let's consider at first the first function
int fun1(int *a, int*b)
{
int i=0;
i+=(&a==&b?1:0);
i+=(a==b?1:0);
i+=(*a==*b?1:0);
return i;
}
It was called like
fun1(p,q)
where the both pointers point to the same variable
int *p=&i;
int *q=&i;
So the function got two equal values as its argument. It is the address of variable i.
Function parameters are its local variable. You can imagine the called function like
int fun1( /*int *a, int*b */)
{
int *a = p;
int *b = q;
//...
}
These local variables occupies different extents of memory. So &a is not equal to &b.
As result the value of expression (&a==&b?1:0) will be equal to 0 and variable i in the statement below
i+=(&a==&b?1:0);
will not be changed
The values stored in variables a and b id the address of variable i in main. As it was said early the two variables contain the same value.
So expression (a==b?1:0) will yield 1 and variable i in the statement below
i+=(a==b?1:0);
will be increased.
As the both pointers points to the same object then expression (*a==*b?1:0) also will yield 1. As result variable i will be increased/
i+=(*a==*b?1:0);
The function will return value 2.
Now let's consider the second function
int fun2(int **a, int*b)
{
int i=0;
i+=(a==&b?1:0);
i+=(*a==b?1:0);
return i;
}
As it was said above parameter b is a local variable of the function. Its address does not equal to the address of argument p
So expression (a==&b?1:0) yields 0.
Expression *a is the value stored in argument p The same value is stored in parameter b
So expression (*a==b?1:0) yields 1.
In total the sum of the return values of the functions will be equal to 3.

Output from *++p and ++*p pointers

I don't understand why I am getting the output 1, 2, 3 for the below code. I believe it should be 1, 2, 2. What is the reason for the first output?
Also, let me point out that there are other questions that pertain to this kind of pointer arithmetic and dereferencing, but the answers to those questions suggest that the output should be 1, 2, 2.
int main()
{
int p[3] = {1,2,3};
int *q = p;
printf("%d\n", *q);
printf("%d\n", *++q);
int x = ++*q;
printf("%d\n", *q);
}
int p[3] = {1,2,3};
int *q = p;
printf("%d\n", *q);
q points to the 1. element, the above prints 1
printf("%d\n", *++q);
q points to the 2. element, the above prints 2.
int x = ++*q;
The 2. element is incremented from 2 to 3.
printf("%d\n", *q);
q points to the 2. element, the above prints 3.
*++q is parsed as *(++q); the result of ++q (which is q + 1) is dereferenced, and as a side effect q is incremented,
++*q is parsed as ++(*q); the result of *q (which is 2) is the operand of ++, which yields 3. As a side effect, *q is incremented.
Remember that both postfix and prefix ++ have a result and a side effect' and that the side effect does not have to be applied immediately after the expression has been evaluated. IOW,
a = b++ * ++c;
will be evaluated as
a = b * (c + 1);
but b and c don't have to be updated until the next sequence point.
Hi,
int p[3] = {1,2,3};
int *q = p;
printf("%d\n", *q); // The output for this line is 1
printf("%d\n", *++q); // Pre Incrementing the 1 which becomes 2
int x = ++*q;
// Here we are making the x point to same location as q and then we are
incrementing the location of the address q. Like q is pointing to the next location and so is the x.Hence the *q gives us 3 which is the value of the incremented location.
printf("%d\n", *q);
Hope it is helpful

Printing a variable in C that was not assigned a value

I put this code into eclipse and run it
main()
{
int *p, *q, *r;
int a = 10, b = 25;
int c[4] = {6,12,18,24};
p = c;
printf("p = %d\n" ,p);
}
the output I get is
p = 2358752
what is this number supposed to represent? Is it the address of the variable?
If what i'm saying above is true would my answer to the following question be correct?
so lets say the following are stored at the following locations
address variables
5000 p
5004 q
5008 r
500C a
5010 b
5014 c[0]
5018 c[1]
501C c[2]
5020 c[3]
so would would the line
p = c;
be 5014?
int *p,
The above statement defines p to be a pointer to an integer.
In the below statement, c is implicitly converted to a pointer to the first element of the array a.
p = c;
// equivalent to
p = &c[0];
Therefore, p contains the address of the first element of the array. Also, the conversion specifier to print an address is %p.
printf("p = %p\n", (void *)p);
// prints the same address
printf("c = %p\n", (void *)c);
Yes, p is the address of c, which is the same as the address of c[0]. And yes, in your second example, p would be equal to 5014.

Resources