C - Increment and decrement pointer, then retrieve value - c

The following code outputs y as a massive integer, not 15. I don't understand why. I know the -- and ++ operators come before the * operator, so it should work.
What the follwing code is trying to say.
/*
Create a variable, set to 15.
Create a pointer to that variable.
Increment the pointer, into undefined memory space.
Decrement the pointer back where it was,
then return the value of what is there,
and save it into the variable y.
Print y.
*/
int main()
{
int x = 15;
int *test = &x;
test++;
int y = *test--;
printf("%d\n", y);
return 0;
}
If instead, I change the code to the following:
int main()
{
int x = 15;
int *test = &x;
test++;
test--;
printf("%d\n", *test);
return 0;
}
That code outputs 15. Why?

The difference is between x++ and ++x, post- and pre-increment of a pointer.
When ++ is after x, the old value is used prior to the increment
When ++ is before x, the new value is used after the increment.
This will work:
int y = *(--test);
Although parentheses are not necessary, it is a good idea to use them for clarity.

Related

C++ pointer increment

Please help me understand how the value of q is initially 1 and later changes to 0.
Code:
#include <stdio.h>
int main()
{
int i=10;
int *p, *q;
p = &i;
printf("%u\n%u\n%u\n",p,q,*q);
*q++=*p++;
printf("%u\n%u\n%u\n%u",p,q,*p,*q);
return 0;
}
Output:
1527896876
1527897120
1
1527896880
1527897124
1527897124
0
int *p, *q;
p = &i;
printf("%u\n%u\n%u\n",p,q,*q);
int* is a wrong type for the format specifier %u. If you pass an argument of wrong type, then the behaviour of your program is undefined.
printf("%u\n%u\n%u\n",p,q,*q);
*q++=*p++;
Here, q has an indeterminate value. It doesn't point to any object. You indirect through the pointer to access an object that it points to. Which is a contradiction because it doesn't point to any object.
Indirecting through an indeterminate pointer results in undefined behaviour.
The behaviour of your program is undefined. That explains everything about the behaviour of the program.
I think what happens is that here
*q++=*p++;
the post-increment operator of q is executed after the assignment.
So, you basically set the value of q to p, and then you increment it.
Also, i don't think the increment operator of p does anything.
For a better understanding look at the following example
#include <stdio.h>
int main() {
int i = 10;
int *p;
int *q = new int[2];
q[0] = 9;
q[1] = 99;
p = &i;
printf("%u\n", *q);
*q++ = *p++;
printf("%u\n", *q);
printf("%u", *--q);
return 0;
}
9
99
10
Notice how, in the end q points to the next element, thanks to the post-increment operator.
Anyway, i have no idea what you are trying to do.

C Pointer address of difference

int main() {
int *x;
int *y;
y = x;
printf("%p %p", &x,&y); // prints 0061FF1C 0061FF18
printf("%p %p", x, y); // prints 00400080 00400080
return 0;
}
Why don't these print the same thing? I thought using just the x and the &x would get to the same value. Also, why are the bottom ones matching if the top one's arent?
When you say y = x in this case it just means that y assumes whatever pointer value x happened to have. You never initialized x with a value, so it's just some random junk.
The address of x and y themselves is going to be different. These are two separate variables representing two separate pointers. You can assign their value to be the same, but their address remains distinct.
You're probably confusing this behaviour with:
int x = 5;
int* y = &x;
Where now y == &x but &x and &y continue to remain distinct.
As C does not have references, you really don't have situations where two independent variables are ever the same address.
Suppose you wrote this:
int main() {
int x = 5;
int y;
y = x;
printf("%p %p", &x, &y);
printf("%d %d", x, y);
}
Would you expect both lines to print the same?
With int *x; you set x as a pointer. Its value is the address of the pointed value.
So:
*x = the integer value
x = the pointer, i.e., the address of the value, address stored at x
&x = the address of the pointer. This is the address of the address.
Then y=x; copies the uninitialized address, not the value.

How can I increment or decrement pointer argument value in function call in C in one line?

I have the following code:
#include <stdio.h>
int foo2(int *px, int *py)
{
int sum = *px + *py;
*px = *px + 1;
*py = *py - 1;
printf("foo2 : res=%d x=%d y=%d\n", sum, *px, *py);
return sum;
}
int main() {
int x = 4, y = 7, res;
res = foo2(&(x++), &(y--));
printf("%d", res);
return 0;
}
I need to increment x, decrement y, then I need to pass them in foo function as arguments.
I have error: lvalue required as unary ‘&’ operand. Also I tried to use x + 1 and y - 1 instead of x++ and y++.
How can I increment x and y values and pass pointer to them in foo2 function call? Is it possible?
You can use the comma operator:
res = foo2((x++, &x), (y--, &y));
However this is not very readable, so unless you have a really good reason it is better to write it as three separate statements:
x++;
y--;
res = foo2(&x, &y);
I just want to add some points here:
C:
In c both the prefix and postfix increment returns the rvalue. So that's the reason you will get an error when you try to get address of post/pre-increment in c.
C++:
But in c++, the prefix (++x) returns lvalue and postfix(x++) returns a rvalue. So in c++, &(++x) is correct whereas &(x++) throws the error.
Note:
I encourage you to read about this a bit more. It will help you a lot to understand much better.

how pointer assignment and increment is working in below example

I am learning the pointers in C. I am little confused about how below program is working
int main()
{
int x=30, *y, *z;
y=&x;
z=y;
*y++=*z++;
x++;
printf("x=%d, y=%p, z=%p\n", x, y, z);
return 0;
}
output is
x=31, y=0x7ffd6c3e1e70, z=0x7ffd6c3e1e70
y and z are pointing to the next integer address of variable x.
I am not able to understand how this line is working
*y++=*z++;
can someone please explain me how this one line is understood by C?
*y++=*z++; actually means
*y = *z;
y += 1*(sizeof(int)); //because int pointers are incremented by 4bytes each time
z += 1*(sizeof(int)); //because int pointers are incremented by 4bytes each time
So pointed value does not affected, pointers are incremented by one.

How to increment a pointer address and pointer's value?

Let us assume,
int *p;
int a = 100;
p = &a;
What will the following code actually do and how?
p++;
++p;
++*p;
++(*p);
++*(p);
*p++;
(*p)++;
*(p)++;
*++p;
*(++p);
I know, this is kind of messy in terms of coding, but I want to know what will actually happen when we code like this.
Note : Lets assume that the address of a=5120300, it is stored in pointer p whose address is 3560200. Now, what will be the value of p & a after the execution of each statement?
First, the ++ operator takes precedence over the * operator, and the () operators take precedence over everything else.
Second, the ++number operator is the same as the number++ operator if you're not assigning them to anything. The difference is number++ returns number and then increments number, and ++number increments first and then returns it.
Third, by increasing the value of a pointer, you're incrementing it by the sizeof its contents, that is you're incrementing it as if you were iterating in an array.
So, to sum it all up:
ptr++; // Pointer moves to the next int position (as if it was an array)
++ptr; // Pointer moves to the next int position (as if it was an array)
++*ptr; // The value pointed at by ptr is incremented
++(*ptr); // The value pointed at by ptr is incremented
++*(ptr); // The value pointed at by ptr is incremented
*ptr++; // Pointer moves to the next int position (as if it was an array). But returns the old content
(*ptr)++; // The value pointed at by ptr is incremented
*(ptr)++; // Pointer moves to the next int position (as if it was an array). But returns the old content
*++ptr; // Pointer moves to the next int position, and then get's accessed, with your code, segfault
*(++ptr); // Pointer moves to the next int position, and then get's accessed, with your code, segfault
As there are a lot of cases in here, I might have made some mistake, please correct me if I'm wrong.
EDIT:
So I was wrong, the precedence is a little more complicated than what I wrote, view it here:
http://en.cppreference.com/w/cpp/language/operator_precedence
checked the program and the results are as,
p++; // use it then move to next int position
++p; // move to next int and then use it
++*p; // increments the value by 1 then use it
++(*p); // increments the value by 1 then use it
++*(p); // increments the value by 1 then use it
*p++; // use the value of p then moves to next position
(*p)++; // use the value of p then increment the value
*(p)++; // use the value of p then moves to next position
*++p; // moves to the next int location then use that value
*(++p); // moves to next location then use that value
The following is an instantiation of the various "just print it" suggestions. I found it instructive.
#include "stdio.h"
int main() {
static int x = 5;
static int *p = &x;
printf("(int) p => %d\n",(int) p);
printf("(int) p++ => %d\n",(int) p++);
x = 5; p = &x;
printf("(int) ++p => %d\n",(int) ++p);
x = 5; p = &x;
printf("++*p => %d\n",++*p);
x = 5; p = &x;
printf("++(*p) => %d\n",++(*p));
x = 5; p = &x;
printf("++*(p) => %d\n",++*(p));
x = 5; p = &x;
printf("*p++ => %d\n",*p++);
x = 5; p = &x;
printf("(*p)++ => %d\n",(*p)++);
x = 5; p = &x;
printf("*(p)++ => %d\n",*(p)++);
x = 5; p = &x;
printf("*++p => %d\n",*++p);
x = 5; p = &x;
printf("*(++p) => %d\n",*(++p));
return 0;
}
It returns
(int) p => 256688152
(int) p++ => 256688152
(int) ++p => 256688156
++*p => 6
++(*p) => 6
++*(p) => 6
*p++ => 5
(*p)++ => 5
*(p)++ => 5
*++p => 0
*(++p) => 0
I cast the pointer addresses to ints so they could be easily compared.
I compiled it with GCC.
With regards to "How to increment a pointer address and pointer's value?" I think that ++(*p++); is actually well defined and does what you're asking for, e.g.:
#include <stdio.h>
int main() {
int a = 100;
int *p = &a;
printf("%p\n",(void*)p);
++(*p++);
printf("%p\n",(void*)p);
printf("%d\n",a);
return 0;
}
It's not modifying the same thing twice before a sequence point. I don't think it's good style though for most uses - it's a little too cryptic for my liking.
Note:
1) Both ++ and * have same precedence(priority), so the associativity comes into picture.
2) in this case Associativity is from **Right-Left**
important table to remember in case of pointers and arrays:
operators precedence associativity
1) () , [] 1 left-right
2) * , identifier 2 right-left
3) <data type> 3 ----------
let me give an example, this might help;
char **str;
str = (char **)malloc(sizeof(char*)*2); // allocate mem for 2 char*
str[0]=(char *)malloc(sizeof(char)*10); // allocate mem for 10 char
str[1]=(char *)malloc(sizeof(char)*10); // allocate mem for 10 char
strcpy(str[0],"abcd"); // assigning value
strcpy(str[1],"efgh"); // assigning value
while(*str)
{
cout<<*str<<endl; // printing the string
*str++; // incrementing the address(pointer)
// check above about the prcedence and associativity
}
free(str[0]);
free(str[1]);
free(str);

Resources