I know this is an Arduino forum and not really a platform to learn C, but I know a lot of folks here are really good when it comes to programming and besides what I am asking will be used in Arduino projects.
I am trying to learn pointers but it doesn't behave as what I expected. I explained it in the comments of my code.
#include <stdio.h>
int main()
{
int x = 1;
int y = 2;
int *p;
p = &x;
printf("%d", p); //p = address of x
puts("");
printf("%d", *p); //*p = value of x, where x = 1
puts("");
y = *p; //y = 1 because *p = x = 1
printf("%d", y);
puts("");
*p = 0; //*p = 0;
printf("%d", y); // y = I expected 0. But why 1? why not 0?
puts("");
printf("%d", x); //x = 0 since *p is 0
}
*p = 0; //*p = 0; // p is pointing at the location of x, so this changes the value of x.
printf("%d", y); // y = 1. I expected 0. But why 1? why not 0? // you have not changed
the value of y. To do so you have to write either y = newValue ; or
p = &y ; *p = newValue;
cyberjupiter:
So does '*p' actually holds a REAL value, or is it just pointing to a value which is assigned by 'p'?
pointers do not hold 'real values' they hold a type and a location
int* p is a pointer it has two properties; it points to some memory location and is of a type (that i very important later on when you understand and start to use them).
dereferencing it (i.e. *p) will allow you to either assign a value to that location:
It seems to me that everytime I assign a variable for example
*p = 1;
y = *p;
'y' copies what the '*p' CURRENTLY points to, in this case '1'
If I reassign
*p = 3;
and prints 'y', I would get the previous value of '*p', which is '1'
If I reassign
*p = 3;
y = *p;
and prints 'y', I would get the last assigned value of '*p', which is '3'.
Forgive me if I seem to be making very idiotic statements, but it looks to me that 'y' will not be changed even if '*p' is changed, unless 'y' is reassigned to '*p'.
int y;
int* ptr0 = &y; // a new int pointer ptr0 which points to the location of y
can be changed to point to another pointer's location:
int y = 10;
int x = 4;
int* ptr0 = &y; // a new int pointer ptr0 which points to the location of y
int* ptr1 = &x; // a new int pointer ptr1 which points to the location of x
Serial.println(*ptr0); // prints "10"
Serial.println(*ptr1); // prints "4"
ptr0 = ptr1; //change ptr0 to point to the location pointed to by ptr1
Serial.println(*ptr0); // prints "4"
If I have code such as this(same as the the original post, with unnecessary stuff commented out)
void main()
{
int x = 1;
int y = 2;
int *p;
p = &x;
y = *p;
}
I would like to deduce this statements;
1. Changing '*p' will only change the value it points to, but does not change 'y' 2. Reassigning 'x' to a new value changes both the value 'x' and the value pointed to by 'p', and still does not change 'y' 3. 'y' CAN only be changed by assigning "p = &y", or by normal assignment "y = newValue"
void main()
{
int x = 1; // create a new variable x and assign it the value 1
int y = 2; // create a new variable y and assign it the value 2
int *p; // create a new int pointer
p = &x; // make the int pointer p point to the location of x
y = *p; // assign y the value pointed to by p -> p points to x -> x = 1
// y now and until it is changed again contains 1
}
cyberjupiter:
I would like to deduce this statements;
1. Changing '*p' will only change the value it points to, but does not change 'y' 2. Reassigning 'x' to a new value changes both the value 'x' and the value pointed to by 'p', and still does not change 'y' 3. 'y' CAN only be changed by assigning "p = &y", or by normal assignment "y = newValue"
if p points to y, then y is changed
yes
not quite, y can be changed by normal assignment or by dereferencing a pointer pointing to the location of y... i.e.:
p = &y; //move p to point to the location of y
*p = newValue; // make the value pointed to by p (which we know is the same location as y) to newValue
*p = newValue; // make the value pointed to by p (which we know is the same location as y) to newValue
That's what I wanted to say actually.
y = *p; // assign y the value pointed to by p -> p points to x -> x = 1
This illustration really starting to give me the 'click' on my brain, but I believe it takes practice to understand it better.
Okay one last question,
p = &y; //move p to point to the location of y
*p = newValue; // make the value pointed to by p (which we know is the same location as y) to newValue
When we assign "*p = someValue", what it actually changes is not the value in '*p'(as you said *p does not hold any value), but the value to what it points to by p, or in the above code 'value in y'
*p = newValue; // make the value pointed to by p (which we know is the same location as y) to newValue
When we assign "*p = someValue", what it actually changes is not the value in '*p'(as you said *p does not hold any value), but the value to what it points to by p, or in the above code 'value in y'
yes, you understand it now!
Pointers are really hard to understand, but as you say one it "clicks" then that is the first hurdle... but since they are used in many differing types of solutions they require 1) practice and 2) practice and 3) even more practice.
I agree that the notation is inherently confusing.
For learning, I think also that it is useful to see it pictorially say by drawing boxes on a sheet of paper representing example storage locations each with their (simplified) address, putting some content in the boxes. That content is either a pointer (the address of another storage location), or a simple value, and drawing arrows from a pointer to the thing being pointed at.
Edit:
If you are using the original C book you'll find example which will no longer compile because of changes in the language eg declaration of function parameter types.
I thought 'p' and 'p' are separate things...when '' should have been appended to the 'type'.
No, the precedence rules dictate that the pointer binds to the variable, not the type.int* p, x;
Here only p is a pointer to int. x is simply an int variable.
…
y = *p; //y = 1 because *p = x = 1
…
*p = 0; //*p = 0;
printf("%d", y); // y = I expected 0. But why 1? why not 0?
puts("");
printf("%d", x); //x = 0 since *p is 0
}
Why would y be 0? You assigned 1 to it. You assigned 0 to *p, but p was pointing at x at the time, not y.