Understanding pointers in C using example code - c

I am learning pointers in C, so I am looking at one example. I tried to add comments to understand what is going on. Is the following code correct? In other words, do my comments describe the operation correctly?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int main(){
int x, y;
int *p1, *p2;
x=-42;
y=163;
p1=&x; //pointer 1 points to the address of x
p2=&y; //pointer 2 points to the address of y
*p1=17; //this just made x=17 because it says that the value at the address where p1 points should be 17
p1=p2; //this just made pointer 1 point at the same place as pointer 2, which means that p1 now points at y
p2=&x; //this just made pointer 2 point at the address of x
//NOW WE HAVE: p1 points at y, p2 points at x, y=17 because of p1
*p1=*p2; //now x=17 as well as y (because the value at the place p2 points, which is x, just became 17)
printf("x=%d, \ny=%d\n", x, y);
return 0;
}

"Check the debugger", for sure. You can also just copy your printf statement after each time you set a value to check, since you're just learning, but this isn't good long-term practice.
I'm not sure if you've quite got the concept and just made a typo mixing up x and y, or if you're making an incorrect assumption, but yes, in your comments:
//NOW WE HAVE: p1 points at y, p2 points at x, y=17 because of p1
you have the location of p1 and p2 correct at this point, but y has not received an assignment since you gave it the value of 163 initially. Assignments to *p1 will affect y, but only after the p1=p2 line.
At the point of this comment, x=17, because of the *p1=17 line a few line up. y is unchanged from the initial assignment.
*p1=*p2; //now x=17 as well as y (because the value at the place p2 points, which is x, just became 17)
y becomes 17 here, as *p1 (which is now y) is assigned the value in *p2, which, as you state, is x.

Related

What is the difference between referencing pointers in a function

I'm creating a function which modifies a variable so it can be used by the function referencing it (parent function?).
Is there a difference between using '&x' compared to using 'z' in the code below?
void changeX(int *p);
int main(void) {
int x = 10;
printf("%d\n",x);
int *z = &x;
changeX(z);
printf("%d\n",x);
// or
changeX(&x);
printf("%d\n",x);
return 0;
}
void changeX(int *p){
*p = *p + *p;
}
wildplasser made a good point, updated to show where I have gotten each value in the output.
Output is:
10
20
40
Both produce the same outcome (change x in the same way), but is there a non-obvious difference between them?
Thanks for the answers in the comments. It makes sense to me now.
The first call initializes the parameter from the argument z, i.e., the value of the argument is the value of the pointer z, which was initialized to be &x, a pointer value that points to the object x. The second call initializes the parameter from the argument &x, which is a pointer value that points to the object x. There is no functional difference between the two calls. In both cases, the parameter p in the function will have the exact same value, a pointer value that points to x, the only difference is where that value came from at the point where function was called…

Understanding of pointers an usage in C

In the code I wrote:
int *p1=&a,**p3=&p1;
after passing p3 as an argument to the function 'change', p1 gets
changed...then the main function has printed p1, p1 takes the value
at double pointer p3(as wrote int **p3=&p1), but it does not take address
of a(int *p1=&a).
This means that value of p1 will be the value at p3, not
the address of variable 'a'? Why the value at double pointer 'p3'
will be considered??
Why not the value of address(&a) which the pointer stored? can anyone clarify
these two lines....
int *p1=&a;
int **p3=&p1;
I understood the concept of double pointers, but need clarification
regarding these two lines...
#include<stdio.h>
void main()
{
int a=2,b=3;
int *p1=&a,*p2=&b,**p3=&p1;
printf("p1=%d, p2=%d, p3=%d\n",p1,p2,p3);
change(p3,p2);
printf("p1=%d, p2=%d, p3=%d\n",p1,p2,p3);
printf("p1=%d\n",p1);
printf("a=%d, b=%d\n",*p1,*p2);
}
void change(int **x,int *z)
{
*x=z;
printf("p1=%d, p2=%d\n",*x,z);
printf("a=%d, b=%d\n",**x,*z);
}
output:
p1=-840577016,p2=-840577012,p3=-840577008
p1=-840577012,p2=-840577012
a=3,b=3
p1=-840577012,p2=-840577012,p3=-840577008
p1=-840577012
a=3,b=3
Because you changed p1 in this line. *x=z;
To explain a bit more you have done this
change(p3,p2)
Now p3 has address of p1. And then you just changed it by assigning to it something else..
That something else is nothing but b's address.
void change(int **x,int *z)
x contains address of p1.
z contains address of b.
Then you said that whatever is the content of x - go there and write there whatever is the content of z. z contained address of b. So now we changed p1-s content to the address of b.
..but in the main will it ignore the line int *p1=&a after p1 gets changed in the function??
Well to the OP - do you think that p1 will get changed here?
int *p1 = &a;
p1 = &b;
We have lastly assigned b's address to p1. The value earlier written os overwritten.
Nothing is ignored - the program did whatever it is said to do.
Another point
Use %p to print a pointer like this
printf("p1=%p, p2=%p, p3=%p\n", (void*)p1, (void*)p2, (void*)p3);

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.

understanding pointers in functions (referring values)

int func (int a, int b, int *c);
int main()
{
int res, x, y, z; //int res, x, y, *z;
printf("enter x \n");
scanf("%i", &x);
printf("enter y \n");
scanf("%i", &y);
res = func(x, y, &z); //res = func(x, y, z);
printf("result addition: %i, result multiplication %i \n", res, *z);
return 0;
}
int func (int a, int b, int *c)
{
int result;
result = a +b;
*c = a*b; //(1) alternative:d=a*b
// c=&d
return result;
}
My problem is, that i don't understand, why this code doesn't work when i write it as i like i did in the comments (//) . Compiler warns me, that z is not initialised, but why isn't that a problem in the working version?
Another thing i don't understand is, why it's correct to refer pointer a value like i did it in (1) but it's wrong in the following code:
int main()
{
int a, *c, *d;
scanf("%i", &a);
*c=a; //wrong
d=&a; //correct
return 0;
}
Compiler warns me, that z is not initialised, but why isn't that a problem in the working version?
The compiler warns you about z being uninitialized because you're passing it by value. And what you're passing is an uninitialized value (which is basically garbage).
It doesn't warn you when you pass the address of z because there's nothing wrong with passing the address of a variable to a pointer. The compiler doesn't check whether you're going to dereference c and use the uninitialized value of z. The compiler's just not that "smart". It assumes you'll do the right thing and just assign z a value by dereferencing c (which you indeed did).
why it's correct to refer pointer a value like i did it in (1) but it's wrong in the following code
As for your 2nd question, the first example works because the parameters of the functions get initialized to whatever values you called the function with.
The 2nd example doesn't work because you're using uninitialized local variables.
At the point where a variable is declared, it comes into existence at some memory location that can be retrieved with &, whereas (if you don't initialize it) the contents of that location is uninitialized. When z is an int, &z is a well-defined pointer because it is the address of a variable, not the contents of one. When z is an int *, z's content is itself a pointer, but it's not initialized; hence the warning (and most likely, your program will crash when scanf() attempts to write to an arbitrary memory location).
your question implies that you have no knowledge about pointers, I suggest you read about them first,
a pointer points to a variable, when you do
*c = a
you are trying to assign a value to the variable pointed to by c with the indirection operator '*',
the problem is that c is not pointing to anything in your code.
in the second one
d = &a;
you make the pointer d point to a. In other words you assign d the address of a. You really should read about pointers first otherwise, whatever we say here will not make sense to you.

Pointers assignment in C

int y=1;
int k=2;
int *p1;
int *p2;
p1=&y;
p2=&k;
p1=p2;
*p1=3;
*p2=4;
printf("%d",y);
I am getting the output as 1, can somebody explain me why !! I was expecting it to be 4.
The below comments explain how this works:
int y=1;
int k=2;
int *p1;
int *p2;
p1=&y; //pointer p1 holds the address of y
p2=&k; //pointer p2 holds the address of k
p1=p2; //pointer p1 now holds the address which p2 holds, which is the address of k
*p1=3; //the value which p1 points to is now 3 (so k equals 3 as well)
*p2=4; //the value which p2 points to is now 4 (so k equals 4 as well)
printf("%d",y); //y is still 1
However if you did printf("%d",k); the value 4 would be printed
To keep this simple let's say &y=3 and &k=4.
int y=1;
int k=2;
int *p1;
int *p2;
p1=&y; // p1=3
p2=&k; // p2=4
p1=p2; // p1=4
*p1=3; // p1=4 so k becomes 3
*p2=4; // p2=4 so k becomes 4
printf("%d",y); // we get 1 because y was never changed
When you do:
p1=p2;
you are basically copying the address of variable k from p2 into p1. So after that step both pointers are pointing to variable k, so if you dereference either p1 or p2 you will actually be changing the value of variable k and not y.
When you do:
*p1 = 3;
You are assiging 3 to variable k. Then when you do:
*p2 = 4;
You are assigning 4 to the variable k again. That's why y remains unaltered and when you print it gives you 1.
The statement p1=p2; sets p1 to point to variable k. So both of the following assignments:
*p1=3;
*p2=4;
only affect variable k, so y remains 1.
Sure, although I'd love to hear how you arrived at 4. p1 gets assigned the address (i.e. pointer to) y, but 2 lines later that gets replaced by the address for k. Thus, neither p1 nor p2 point to y, so y doesn't change.

Resources