Related
I am currently trying to understand pointers in C but I am having a hard time understanding this code:
int a[10];
int *p = a+9;
while ( p > a )
*p-- = (int)(p-a);
I understand the code to some degree. I can see that an array with 10 integer elements is created then a pointer variable to type int is declared. (But I don't understand what a+9 means: does this change the value of the array?).
It would be very helpful if someone could explain this step by step, since I am new to pointers in C.
When used in an expression1, the name of an array in C, 'decays' to a pointer to its first element. Thus, in the expression a + 9, the a is equivalent to an int* variable that has the value of &a[0].
Also, pointer arithmetic works in units of the pointed-to type; so, adding 9 to &a[0] means that you get the address of a[9] – the last element of the array. So, overall, the p = a + 9 expression assigns the address of the array's last element to the p pointer (but it does not change anything in that array).
The subsequent while loop, however, does change the values of the array's elements, setting each to the value of its position (the result of the p - a expression) and decrementing the address in p by the size of an int. (Well, that what it's probably intended to do; but, as mentioned in the comments, the use of such "unsequenced operations" – i.e. the use of p-- and p - a in the same statement – is actually undefined behaviour because, in this case, the C Standard does not dictate which of those two expressions should be evaluated first.)
To avoid that undefined behaviour, the code should be written to use an explicit intermediate, like this:
int main()
{
int a[10];
int* p = a + 9;
while (p > a) {
int n = (int)(p - a); // Get the value FIRST ...
*p-- = n; // ... only THEN assign it
}
return 0;
}
1 There two exceptions: when that array name is used as the operand of a sizeof operator or of the unary & (address of) operator.
int a[10];
This declares an array on e.g. the stack. a represents the starting address of the array. The declaration tells the compiler that a will hold 10 integers. C assumes you know what you are doing so it is up to you to keep yourself in that range.
int *p = a+9;
p is declared a pointer e.g. like a RL street address. When you add an offset to a an offset is added to the address a. The compiler converts the offset like +5 to bytes +5*sizeof(int) so you don't need to think about that, so your p pointer is now pointing inside the array at offset 9 - which is the last int in the array a since index starts at 0 in C.
while( p > a )
The condition says that do this while the address of what p is pointing to is larger than the address where a is.
*p-- = (int)(p-a);
here the value what p points to is overwritten with a crude(1) subtraction between current p and starting address a before the pointer p is decremented.
(1) Undefined Behavior
I read different things on the Internet and got confused, because every website says different things.
I read about * referencing operator and & dereferencing operator; or that referencing means making a pointer point to a variable and dereferencing is accessing the value of the variable that the pointer points to. So I got confused.
Can I get a simple but thorough explanation about "referencing and dereferencing"?
Referencing means taking the address of an existing variable (using &) to set a pointer variable.
In order to be valid, a pointer has to be set to the address of a variable of the same type as the pointer, without the asterisk:
int c1;
int* p1;
c1 = 5;
p1 = &c1;
//p1 references c1
Dereferencing a pointer means using the * operator (asterisk character) to retrieve the value from the memory address that is pointed by the pointer:
NOTE: The value stored at the address of the pointer must be a value OF THE SAME TYPE as the type of variable the pointer "points" to, but there is no guarantee this is the case unless the pointer was set correctly. The type of variable the pointer points to is the type less the outermost asterisk.
int n1;
n1 = *p1;
Invalid dereferencing may or may not cause crashes:
Dereferencing an uninitialized pointer can cause a crash
Dereferencing with an invalid type cast will have the potential to cause a crash.
Dereferencing a pointer to a variable that was dynamically allocated and was subsequently de-allocated can cause a crash
Dereferencing a pointer to a variable that has since gone out of scope can also cause a crash.
Invalid referencing is more likely to cause compiler errors than crashes, but it's not a good idea to rely on the compiler for this.
References:
http://www.codingunit.com/cplusplus-tutorial-pointers-reference-and-dereference-operators
& is the reference operator and can be read as “address of”.
* is the dereference operator and can be read as “value pointed by”.
http://www.cplusplus.com/doc/tutorial/pointers/
& is the reference operator
* is the dereference operator
http://en.wikipedia.org/wiki/Dereference_operator
The dereference operator * is also called the indirection operator.
I've always heard them used in the opposite sense:
& is the reference operator -- it gives you a reference (pointer) to some object
* is the dereference operator -- it takes a reference (pointer) and gives you back the referred to object;
For a start, you have them backwards: & is reference and * is dereference.
Referencing a variable means accessing the memory address of the variable:
int i = 5;
int * p;
p = &i; //&i returns the memory address of the variable i.
Dereferencing a variable means accessing the variable stored at a memory address:
int i = 5;
int * p;
p = &i;
*p = 7; //*p returns the variable stored at the memory address stored in p, which is i.
//i is now 7
find the below explanation:
int main()
{
int a = 10;// say address of 'a' is 2000;
int *p = &a; //it means 'p' is pointing[referencing] to 'a'. i.e p->2000
int c = *p; //*p means dereferncing. it will give the content of the address pointed by 'p'. in this case 'p' is pointing to 2000[address of 'a' variable], content of 2000 is 10. so *p will give 10.
}
conclusion :
& [address operator] is used for referencing.
* [star operator] is used for de-referencing .
The context that * is in, confuses the meaning sometimes.
// when declaring a function
int function(int*); // This function is being declared as a function that takes in an 'address' that holds a number (so int*), it's asking for a 'reference', interchangeably called 'address'. When I 'call'(use) this function later, I better give it a variable-address! So instead of var, or q, or w, or p, I give it the address of var so &var, or &q, or &w, or &p.
//even though the symbol ' * ' is typically used to mean 'dereferenced variable'(meaning: to use the value at the address of a variable)--despite it's common use, in this case, the symbol means a 'reference', again, in THIS context. (context here being the declaration of a 'prototype'.)
//when calling a function
int main(){
function(&var); // we are giving the function a 'reference', we are giving it an 'address'
}
So, in the context of declaring a type such as int or char, we would use the dereferencer ' * ' to actually mean the reference (the address), which makes it confusing if you see an error message from the compiler saying: 'expecting char*' which is asking for an address.
In that case, when the * is after a type (int, char, etc.) the compiler is expecting a variable's address. We give it this by using a reference operator, alos called the address-of operator ' & ' before a variable. Even further, in the case I just made up above, the compiler is expecting the address to hold a character value, not a number. (type char * == address of a value that has a character)
int* p;
int *a; // both are 'pointer' declarations. We are telling the compiler that we will soon give these variables an address (with &).
int c = 10; //declare and initialize a random variable
//assign the variable to a pointer, we do this so that we can modify the value of c from a different function regardless of the scope of that function (elaboration in a second)
p = c; //ERROR, we assigned a 'value' to this 'pointer'. We need to assign an 'address', a 'reference'.
p = &c; // instead of a value such as: 'q',5,'t', or 2.1 we gave the pointer an 'address', which we could actually print with printf(), and would be something like
//so
p = 0xab33d111; //the address of c, (not specifically this value for the address, it'll look like this though, with the 0x in the beggining, the computer treats these different from regular numbers)
*p = 10; // the value of c
a = &c; // I can still give c another pointer, even though it already has the pointer variable "p"
*a = 10;
a = 0xab33d111;
Think of each variable as having a position (or an index value if you are familiar with arrays) and a value. It might take some getting used-to to think of each variable having two values to it, one value being it's position, physically stored with electricity in your computer, and a value representing whatever quantity or letter(s) the programmer wants to store.
//Why it's used
int function(b){
b = b + 1; // we just want to add one to any variable that this function operates on.
}
int main(){
int c = 1; // I want this variable to be 3.
function(c);
function(c);// I call the function I made above twice, because I want c to be 3.
// this will return c as 1. Even though I called it twice.
// when you call a function it makes a copy of the variable.
// so the function that I call "function", made a copy of c, and that function is only changing the "copy" of c, so it doesn't affect the original
}
//let's redo this whole thing, and use pointers
int function(int* b){ // this time, the function is 'asking' (won't run without) for a variable that 'points' to a number-value (int). So it wants an integer pointer--an address that holds a number.
*b = *b + 1; //grab the value of the address, and add one to the value stored at that address
}
int main(){
int c = 1; //again, I want this to be three at the end of the program
int *p = &c; // on the left, I'm declaring a pointer, I'm telling the compiler that I'm about to have this letter point to an certain spot in my computer. Immediately after I used the assignment operator (the ' = ') to assign the address of c to this variable (pointer in this case) p. I do this using the address-of operator (referencer)' & '.
function(p); // not *p, because that will dereference. which would give an integer, not an integer pointer ( function wants a reference to an int called int*, we aren't going to use *p because that will give the function an int instead of an address that stores an int.
function(&c); // this is giving the same thing as above, p = the address of c, so we can pass the 'pointer' or we can pass the 'address' that the pointer(variable) is 'pointing','referencing' to. Which is &c. 0xaabbcc1122...
//now, the function is making a copy of c's address, but it doesn't matter if it's a copy or not, because it's going to point the computer to the exact same spot (hence, The Address), and it will be changed for main's version of c as well.
}
Inside each and every block, it copies the variables (if any) that are passed into (via parameters within "()"s). Within those blocks, the changes to a variable are made to a copy of that variable, the variable uses the same letters but is at a different address (from the original). By using the address "reference" of the original, we can change a variable using a block outside of main, or inside a child of main.
Referencing
& is the reference operator. It will refer the memory address to the pointer variable.
Example:
int *p;
int a=5;
p=&a; // Here Pointer variable p refers to the address of integer variable a.
Dereferencing
Dereference operator * is used by the pointer variable to directly access the value of the variable instead of its memory address.
Example:
int *p;
int a=5;
p=&a;
int value=*p; // Value variable will get the value of variable a that pointer variable p pointing to.
Reference of the de-referenced pointer is also same as the address of the pointed variable.
Explanation :-
int var = 3;
int *p;
p = &var;
so,
let's think address of var is : ABCDE
then,
p = ABCDE and
&*p = ABCDE;
that means put &* together ,neutral the referencing and de-referencing.
also when declaring a function ,
the function's arguments should be the pointers,
and in the arguments of the this function when calling it in main method are should been with & operator.
it's bit confusing.
But remember that
int *p = &var; is also correct as the above pointer declaration.
See the two codes below!
int main() {
int a = 12;
int *p;
*p = a;
}
and the this code,
int main() {
int a = 12;
int *p;
p = &a;
}
In the first piece of code dereferenced the pointer as this *p = a, and in the second piece of code, the address of variabe a is set to the pointer variable.
My question is what is the difference between both pieces of codes?
In your first piece of code:
int main() {
int a = 12;
int *p;
*p = a;
}
you have a serious case of undefined behaviour because, what you are trying to do is assign the value of a to the int variable that p currently points to. However, p has not been assigned an 'address', so it will have an arbitrary - and invalid - value! Some compilers may initialise p to zero (or NULL) but that is still an invalid address (on most systems).
Your second code snippet is 'sound' but, as it stands, doesn't actually achieve anything:
int main() {
int a = 12;
int *p;
p = &a;
}
Here, you are assigning a value (i.e. an address) to your pointer variable, p; in this case, p now points to the a variable (that is, it's value is the address of a).
So, if you appended code like this (to the end of your second snippet):
*p = 42;
and then printed out the value of a, you would see that its value has been changed from the initially-given 12 to 42.
Feel free to ask for further clarification and/or explanation.
Declaring *p and a is reserving some space in memory, for a pointer in first case, for what a is in the 2nd case (an int).
In these both cases, their values are not initialized if you don't put anything in it. That doesn't mean there is nothing in it, as that is not possible. It means their values are undetermined, kind of "random" ; the loader just put the code/data in memory when requested, and the space occupied by p, and the one occupied by a, are both whatever the memory had at the time of loading (could be also at time of compilation, but anyway, undetermined).
So you take a big risk in doing *p = a in the 1st case, since you ask the processeur to take the bytes "inside" a and store them wherever p points at. Could be within the bounds of your data segments, in the stack, somewhere it won't cause an immediate problem/crash, but the chances are, it's very likely that won't be ok!
This is why this issue is said to cause "Undefined Behavior" (UB).
When you initialized a pointer you can use *p to access at the value of pointer of the pointed variable and not the address of the pointed variable but it's not possible to affect value like that (with *p=a). Because you try to affect a value without adress of variable.
The second code is right use p = &a
The first one is bad:
int main() {
int a = 12;
int *p;
*p = a;
}
It means: put the value of variable a into location, pointed by pointer p. But what the p points? probably nothing (NULL) or any random address. In best case, it can make execution error like access violation or segmentation fault. In worst case, it can overwrite any existing value of totally unknown variable, resulting in problems, which are very hard to investigate.
The second one is OK.
int main() {
int a = 12;
int *p;
p = &a;
}
It means: get the pointer to (existing) variable a and assign it to pointer p. So, this will work OK.
What is the difference between dereferencing and assigning the address of a variable to pointer variable in C?
The latter is the premise for the first. They are separate steps to achieve the benefit of pointer dereferencing.
For the the explanation for where the difference between those are, we have to look what these guys are separately:
What is dereferencing the pointer?
First we need to look what a reference is. A reference is f.e. an identifier for an object. We could say "Variable a stands for the value of 12." - thus, a is a reference to the value of 12.
The identifier of an object is a reference for the value stored within.
The same goes for pointers. pointers are just like usual objects, they store a value inside, thus they refer to the stored values in them.
"Dereferencing" is when we "disable" this connection to the usual value within and use the identifier of p to access/refer to a different value than the value stored in p.
"Dereferencing a pointer" means simply, you use the pointer to access the value stored in another object, f.e. 12 in a instead through its own identifier of a.
To dereference the pointer the * dereference operator needs to precede the pointer variable, like *p.
What is assigning the address of a variable to a pointer?
We are achieving the things stated in "What is dereferencing a pointer?", by giving the pointer an address of another object as its value, in analogy like we assign a value to a usual variable.
But as opposed to usual object initializations/assignments, for this we need to use the & ampersand operator, preceding the variable, whose value the pointer shall point to and the * dereference operator, preceding the pointer, has to be omitted, like:
p = &a;
Therafter, The pointer "points" to the address the desired value is stored at.
Steps to dereferencing a pointer properly:
First thing to do is to declare a pointer, like:
int *p;
In this case, we declare a pointer variable of p which points to an object of type int.
Second step is to initialize the pointer with an address value of an object of type int:
int a = 12;
p = &a; //Here we assign the address of `a` to p, not the value of 12.
Note: If you want the address value of an object, like a usual variable, you need to use the unary operator of &, preceding the object.
If you have done these steps, you are finally be able to access the value of the object the pointer points to, by using the *operator, preceding the pointer object:
*p = a;
My question is what is the difference between both pieces of codes?
The difference is simply as that, that the first piece of code:
int main() {
int a = 12;
int *p;
*p = a;
}
is invalid for addressing an object by dereferencing a pointer. You cannot assign a value to the pointer´s dereference, if there isn´t made one reference before to which the pointer do refer to.
Thus, your assumption of:
In the first piece of code I dereferenced the pointer as this *p = a...
is incorrect.
You do not be able to dereference the pointer at all in the proper way with *p = a in this case, because the pointer p doesn´t has any reference, to which you are be able to dereference the pointer correctly to.
In fact, you are assigning the value of a with the statement of *p = a somewhere into the Nirwana of your memory.
Normally, the compiler shall never pass this through without an error.
If he does and you later want to use the value, which you think you´d assigned properly by using the pointer, like printf("%d",*p) you should get a Segmentation fault (core dumped).
I am trying to figure out all the possible ways I could fill in int pointer k considering the following givens:
int i = 40;
int *p = &i;
int *k = ___;
So far I came up with "&i" and "p". However, is it possible to fill in the blank with "*&p" or "&*p"?
My understanding of "*&p" is that it is dereferencing the address of an integer pointer. Which to me means if printed out would output the content of p, which is &i. Or is that not possible when initializing an int pointer? Or is it even possible at all anytime?
I understand "&*p" as the memory address of the integer *p points to. This one I am really unsure about also.
If anyone has any recommendations or suggestions I will greatly appreciate it! Really trying to understand pointers better.
Pointer Basics
A pointer is simply a normal variable that holds the address of something else as its value. In other words, a pointer points to the address where something else can be found. Where you normally think of a variable holding an immediate values, such as int i = 40;, a pointer (e.g. int *p = &i;) would simply hold the address where 40 is stored in memory.
If you need the value stored at the memory address p points to, you dereference p using the unary '*' operator, e.g. int j = *p; will initialize j = 40).
Since p points to the address where 40 is stored, if you change that value at that address (e.g. *p = 41;) 41 is now stored at the address where 40 was before. Since p points to the address of i and you have changed the value at that address, i now equals 41. However j resides in another memory location and its value was set before you changed the value at the address for i, the value for j remains 40.
If you want to create a second pointer (e.g. int *k;) you are just creating another variable that holds an address as its value. If you want k to reference the same address held by p as its value, you simply initialize k the same way you woul intialize any other varaible by assigning its value when it is declared, e.g. int *k = p; (which is the same as assigning k = p; at some point after initialization).
Pointer Arithmetic
Pointer arithmetic works the same way regardless of the type of object pointed to because the type of the pointer controls the pointer arithmetic, e.g. with a char * pointer, pointer+1 points to the next byte (next char), for an int * pointer (normal 4-byte integer), pointer+1 will point to the next int at an offset 4-bytes after pointer. (so a pointer, is just a pointer.... where arithmetic is automatically handled by the type)
Chaining & and * Together
The operators available to take the address of an object and dereference pointers are the unary '&' (address of) operator and the unary '*' (dereference) operator. '&' in taking the address of an object adds one level of indirection. '*' in dereferening a pointer to get the value (or thing) pointed to by the pointer removes one level of indirection. So as #KamilCuk explained in example in his comment it does not matter how many times you apply one after the other, one simply adds and the other removes a level of indirection making all but the final operator superfluous.
(note: when dealing with an array-of-pointers, the postfix [..] operator used to obtain the pointer at an index of the array also acts to derefernce the array of pointers removing one level of indirection)
Your Options
Given your declarations:
int i = 40;
int *p = &i;
int *k = ___;
and the pointer summary above, you have two options, both are equivalent. You can either initialize the pointer k with the address of i directly, e.g.
int *k = &i;
or you can initialize k by assinging the address held by p, e.g.
int *k = p;
Either way, k now holds, as its value, the memory location for i where 40 is currently stored.
I am a little bit unsure what you're trying to do but,
int* p = &i;
now, saying &*p is really just like saying p since this gives you the address.
Just that p is much clearer.
The rule is (quoting C11 standard footnote 102) that for any pointer E
&*E is equivalent to E
You can have as many &*&*&*... in front of any pointer type variable that is on the right side of =.
With the &*&*&* sequence below I denote: zero or more &* sequences. I've put a space after it so it's, like, somehow visible. So: we can assign pointer k to the address of i:
int *k = &*&*&* &i;
and assign k to the same value as p has:
int *k = &*&*&* p;
We can also take the address of pointer p, so do &p, it will have int** - ie. it will be a pointer to a pointer to int. And then we can dereference that address. So *&p. It will be always equal to p.
int *k = &*&*&* *&p;
is it possible to fill in the blank with "*&p" or "&*p"?
Yes, both are correct. The *&p first takes the address of p variables then deferences it, as I said above. The *&variable should be always equal to the value of variable. The second &*p is equal to p.
My understanding of "*&p" is that it is dereferencing the address of an integer pointer. Which to me means if printed out would output the content of p, which is &i. Or is that not possible when initializing an int pointer? Or is it even possible at all anytime?
Yes and yes. It is possible, anytime, with any type. The &* is possible with complete types only.
Side note: It's get really funny with functions. The dereference operator * is ignored in front of a function or a function pointer. This is just a rule in C. See ex. this question. You can have a infinite sequence of * and & in front of a function or a function pointer as long as there are no && sequences in it. It gets ridiculous:
void func(void);
void (*funcptr)(void) = ***&***********&*&*&*&****func;
void (*funcptr2)(void) = ***&***&***&***&***&*******&******&**funcptr;
Both funcptr and funcptr2 are assigned the same value and both point to function func.
I read different things on the Internet and got confused, because every website says different things.
I read about * referencing operator and & dereferencing operator; or that referencing means making a pointer point to a variable and dereferencing is accessing the value of the variable that the pointer points to. So I got confused.
Can I get a simple but thorough explanation about "referencing and dereferencing"?
Referencing means taking the address of an existing variable (using &) to set a pointer variable.
In order to be valid, a pointer has to be set to the address of a variable of the same type as the pointer, without the asterisk:
int c1;
int* p1;
c1 = 5;
p1 = &c1;
//p1 references c1
Dereferencing a pointer means using the * operator (asterisk character) to retrieve the value from the memory address that is pointed by the pointer:
NOTE: The value stored at the address of the pointer must be a value OF THE SAME TYPE as the type of variable the pointer "points" to, but there is no guarantee this is the case unless the pointer was set correctly. The type of variable the pointer points to is the type less the outermost asterisk.
int n1;
n1 = *p1;
Invalid dereferencing may or may not cause crashes:
Dereferencing an uninitialized pointer can cause a crash
Dereferencing with an invalid type cast will have the potential to cause a crash.
Dereferencing a pointer to a variable that was dynamically allocated and was subsequently de-allocated can cause a crash
Dereferencing a pointer to a variable that has since gone out of scope can also cause a crash.
Invalid referencing is more likely to cause compiler errors than crashes, but it's not a good idea to rely on the compiler for this.
References:
http://www.codingunit.com/cplusplus-tutorial-pointers-reference-and-dereference-operators
& is the reference operator and can be read as “address of”.
* is the dereference operator and can be read as “value pointed by”.
http://www.cplusplus.com/doc/tutorial/pointers/
& is the reference operator
* is the dereference operator
http://en.wikipedia.org/wiki/Dereference_operator
The dereference operator * is also called the indirection operator.
I've always heard them used in the opposite sense:
& is the reference operator -- it gives you a reference (pointer) to some object
* is the dereference operator -- it takes a reference (pointer) and gives you back the referred to object;
For a start, you have them backwards: & is reference and * is dereference.
Referencing a variable means accessing the memory address of the variable:
int i = 5;
int * p;
p = &i; //&i returns the memory address of the variable i.
Dereferencing a variable means accessing the variable stored at a memory address:
int i = 5;
int * p;
p = &i;
*p = 7; //*p returns the variable stored at the memory address stored in p, which is i.
//i is now 7
find the below explanation:
int main()
{
int a = 10;// say address of 'a' is 2000;
int *p = &a; //it means 'p' is pointing[referencing] to 'a'. i.e p->2000
int c = *p; //*p means dereferncing. it will give the content of the address pointed by 'p'. in this case 'p' is pointing to 2000[address of 'a' variable], content of 2000 is 10. so *p will give 10.
}
conclusion :
& [address operator] is used for referencing.
* [star operator] is used for de-referencing .
The context that * is in, confuses the meaning sometimes.
// when declaring a function
int function(int*); // This function is being declared as a function that takes in an 'address' that holds a number (so int*), it's asking for a 'reference', interchangeably called 'address'. When I 'call'(use) this function later, I better give it a variable-address! So instead of var, or q, or w, or p, I give it the address of var so &var, or &q, or &w, or &p.
//even though the symbol ' * ' is typically used to mean 'dereferenced variable'(meaning: to use the value at the address of a variable)--despite it's common use, in this case, the symbol means a 'reference', again, in THIS context. (context here being the declaration of a 'prototype'.)
//when calling a function
int main(){
function(&var); // we are giving the function a 'reference', we are giving it an 'address'
}
So, in the context of declaring a type such as int or char, we would use the dereferencer ' * ' to actually mean the reference (the address), which makes it confusing if you see an error message from the compiler saying: 'expecting char*' which is asking for an address.
In that case, when the * is after a type (int, char, etc.) the compiler is expecting a variable's address. We give it this by using a reference operator, alos called the address-of operator ' & ' before a variable. Even further, in the case I just made up above, the compiler is expecting the address to hold a character value, not a number. (type char * == address of a value that has a character)
int* p;
int *a; // both are 'pointer' declarations. We are telling the compiler that we will soon give these variables an address (with &).
int c = 10; //declare and initialize a random variable
//assign the variable to a pointer, we do this so that we can modify the value of c from a different function regardless of the scope of that function (elaboration in a second)
p = c; //ERROR, we assigned a 'value' to this 'pointer'. We need to assign an 'address', a 'reference'.
p = &c; // instead of a value such as: 'q',5,'t', or 2.1 we gave the pointer an 'address', which we could actually print with printf(), and would be something like
//so
p = 0xab33d111; //the address of c, (not specifically this value for the address, it'll look like this though, with the 0x in the beggining, the computer treats these different from regular numbers)
*p = 10; // the value of c
a = &c; // I can still give c another pointer, even though it already has the pointer variable "p"
*a = 10;
a = 0xab33d111;
Think of each variable as having a position (or an index value if you are familiar with arrays) and a value. It might take some getting used-to to think of each variable having two values to it, one value being it's position, physically stored with electricity in your computer, and a value representing whatever quantity or letter(s) the programmer wants to store.
//Why it's used
int function(b){
b = b + 1; // we just want to add one to any variable that this function operates on.
}
int main(){
int c = 1; // I want this variable to be 3.
function(c);
function(c);// I call the function I made above twice, because I want c to be 3.
// this will return c as 1. Even though I called it twice.
// when you call a function it makes a copy of the variable.
// so the function that I call "function", made a copy of c, and that function is only changing the "copy" of c, so it doesn't affect the original
}
//let's redo this whole thing, and use pointers
int function(int* b){ // this time, the function is 'asking' (won't run without) for a variable that 'points' to a number-value (int). So it wants an integer pointer--an address that holds a number.
*b = *b + 1; //grab the value of the address, and add one to the value stored at that address
}
int main(){
int c = 1; //again, I want this to be three at the end of the program
int *p = &c; // on the left, I'm declaring a pointer, I'm telling the compiler that I'm about to have this letter point to an certain spot in my computer. Immediately after I used the assignment operator (the ' = ') to assign the address of c to this variable (pointer in this case) p. I do this using the address-of operator (referencer)' & '.
function(p); // not *p, because that will dereference. which would give an integer, not an integer pointer ( function wants a reference to an int called int*, we aren't going to use *p because that will give the function an int instead of an address that stores an int.
function(&c); // this is giving the same thing as above, p = the address of c, so we can pass the 'pointer' or we can pass the 'address' that the pointer(variable) is 'pointing','referencing' to. Which is &c. 0xaabbcc1122...
//now, the function is making a copy of c's address, but it doesn't matter if it's a copy or not, because it's going to point the computer to the exact same spot (hence, The Address), and it will be changed for main's version of c as well.
}
Inside each and every block, it copies the variables (if any) that are passed into (via parameters within "()"s). Within those blocks, the changes to a variable are made to a copy of that variable, the variable uses the same letters but is at a different address (from the original). By using the address "reference" of the original, we can change a variable using a block outside of main, or inside a child of main.
Referencing
& is the reference operator. It will refer the memory address to the pointer variable.
Example:
int *p;
int a=5;
p=&a; // Here Pointer variable p refers to the address of integer variable a.
Dereferencing
Dereference operator * is used by the pointer variable to directly access the value of the variable instead of its memory address.
Example:
int *p;
int a=5;
p=&a;
int value=*p; // Value variable will get the value of variable a that pointer variable p pointing to.
Reference of the de-referenced pointer is also same as the address of the pointed variable.
Explanation :-
int var = 3;
int *p;
p = &var;
so,
let's think address of var is : ABCDE
then,
p = ABCDE and
&*p = ABCDE;
that means put &* together ,neutral the referencing and de-referencing.
also when declaring a function ,
the function's arguments should be the pointers,
and in the arguments of the this function when calling it in main method are should been with & operator.
it's bit confusing.
But remember that
int *p = &var; is also correct as the above pointer declaration.