why results of these two functions are different? - c

I expected results are same. Two functions do same thing but
why they are different?
I think its related to pointers.
void changer(int n){
n = 20;
}
void arrayChanger(int n[]){
n[0] = 20;
}
int main()
{
int a = 5;
int ar[1] = {5};
changer(a);
arrayChanger(ar);
printf("%d\n",a);
printf("%d\n",ar[0]);
return 0;
}

Arguments are passed by value unless the argument is specifically declared to be passed by reference, and arrays will decay to a pointer to their first element when passed to functions.
The function changer does not update the actual variable a since it only receives its value, not the variable itself.
If you want to update a value in a function call, you need to pass it by reference:
void make20(int *a)
{
*a = 20;
}
The call would then look like:
int n = 5;
make20(&n);
// now n = 20

In changer(a), you pass an int as the parameter. This int is passed by value. That means that when changer executes, it simply receives the int 5 as a parameter and sets the parameter to 20. However, since the parameter is passed by value, there is no change to the parameter outside of the function.
In arrayChanger(ar), you pass an array as the parameter. As mentioned by Osiris, when passing an array to a function, it 'decays' to a pointer to the first element of said array. Therefore, in arrayChanger, you set the value at the pointer to 20. This means that after execution, the value at the pointer (which has remained constant) is now 20 rather than the original 5.

Related

Something passed to a function as pointers to type [duplicate]

Before I start I want to tell you I am learning to program.
What is the difference between Passing the variable to function and passing an array to the function in C?
When we pass a variable to function we are just passing the value of function. But when we pass an array we are passing somehow a pointer because when we do some changes on an array inside a function, actual array gets changed.
In order to make my question clear I am attaching code which will explain what I am asking-
Code 1:
//Passing variable to function
#include<stdio.h>
void swap(int x, int y);
int main(void)
{
//Nothing is happening to real values of variables
int x, y;
x = 1;
y = 2;
swap(x, y);
printf("%d = x \n %d = y", x, y);
}
void swap(int x, int y)
{
int temp;
temp = x;
x = y;
y = temp;
}
Code 2:
//Here you can see the values of arrays are swapped.
#include<stdio.h>
void swap(int arr[]);
int main(void)
{
int idx, array[2];
for(idx = 0; idx < 2; idx++ )
{
scanf("%d", &array[idx]);
}
swap(array);
for(idx = 0; idx < 2; idx++, printf("\n"))
{
printf("%d", array[idx]);
}
}
void swap(int arr[])
{
int temp;
temp = arr[0];
arr[0] = arr[1];
arr[1] = temp;
}
Maybe my question is still unclear but I just want to know why the values of the array gets changed in main function as when we call the function we are just passing a function value of that variable.
In the both cases when a variable as you are saying is passed to a function or an array is passed to a function there is passed a value.
But in the first case there is passed the value of the variable while in the second case there is passed the value of the pointer to first element of an array.
Arrays used in expressions with rare exceptions are converted to pointers to their first elements.
From the C Standard (6.3.2.1 Lvalues, arrays, and function designators)
3 Except when it is the operand of the sizeof operator or the unary &
operator, or is a string literal used to initialize an array, an
expression that has type ‘‘array of type’’ is converted to an
expression with type ‘‘pointer to type’’ that points to the initial
element of the array object and is not an lvalue. If the array object
has register storage class, the behavior is undefined.
So having a pointer to an object you can change the pointed object.
Let's assume that you have two functions.
void f( int x )
{
x = 10;
}
and
void g( int *px )
{
*px = 10;
}
and their calls
int n = 0;
f( n );
g( &n );
You can imagine the function definitions and their calls the following way
int n = 0;
f( n );
g( &n );
//...
void f( /* int x */ )
{
int x = n;
x = 10;
}
void g( /* int *px */ )
{
int *px = &n;
*px = 10;
}
That is the both functions deal with copies of values of the expressions used as function arguments. But in case of the function g as the function gets the value of the address of the pointed object n you can change the pointed object n using the pointer (address).
In the terms of C passing an object to a function indirectly through a pointer to the object is called passing by reference.
From the C Standard
— A pointer type may be derived from a function type or an object
type, called the referenced type. A pointer type describes an object
whose value provides a reference to an entity of the referenced
type. A pointer type derived from the referenced type T is sometimes
called ‘‘pointer to T’’. The construction of a pointer type from a
referenced type is called ‘‘pointer type derivation’’. A pointer type
is a complete object type.
Pay attention to that a function declaration like this
void f( int a[], size_t n );
is equivalent to the following declaration
void f( int *a, size_t n );
And the both declare the same one function.
If you have an array as for example
#define N 10
//...
int a[N];
then it is passed to the function like
f( a, N );
then as it is followed form the first quote from the C Standard the array designator is converted to pointer to its first element. And having this pointer in the function you can change any element of the array because each element of the array in fact is passed by reference. Using the pointer arithmetic you can change any element of the pointed array. For example
void f( int *a, size_t n )
{
for ( int i = 0; i < n; i++ )
{
a[i] = i;
// that is the same as
// *( a + i ) = i;
}
}
When you pass an array, you are actually passing the base address of the same, which is a pointer to the first array element in the memory. It is inherently a call by reference, so you don't need to explicitly use a reference or & while passing into your swap function. arr decays to &(arr[0]).
On the other hand, variables are not by default passed by value, and you need to explicitly use a & to pass them by reference to get their values swapped in their memory locations and not just specific to the scope of the swap function.
What is the difference between Passing the variable to function and passing an array to the function in C?
You cannot pass an array as it is to a function. The C syntax does not allow that. When you provide the identifier of an array as argument it decays to a pointer to the first element of the array - so you pass the array by reference to its first element.
If the relative parameter of the function is of the matching pointer type, here int * or int a[], this is permissible.
Instead when providing a variable as argument you pass it by value. Means you do not access the variable provided as argument in the function itself. Rather the value is copied into a local variable of the function.
If you want to change the value of the variable passed itself, you need to use the & ampersand operator to gather the address of the variable itself. This is only permissible if the relative parameter is of matching pointer type as above.
Thus, In the first example you do not swap the values of x and y in main(). You only change x and y inside of swap() which is pretty useless.
If you want to swap xand y in main you need to define swap() as:
void swap(int* x, int* y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
and call swap() like:
swap(&x, &y);
I suggest you to learn more about pointers.
You are not passing the array as copy. It is only a pointer pointing to the address where the first element is in memory.
When passing an array as a parameter, this
void arraytest(int a[])
means exactly the same as
void arraytest(int *a)
so you are modifying the values in main. However in C function arguments are always passed by value. In case of an array (variable), while passed as a function argument, it decays to the pointer to the first element of the array. The pointer is then passed-by-value, as usual.
An array is a special variable. When you pass a regular variable to a function as an argument, its value is copied to a local variable pertaining to the function.
When you pass an array to a function as an argument, the address of the first element of the array is copied to a local variable pertaining to the function.
That is basically the difference between passing a regular variable and passing an array to a function.
There is one issue with your perception though. If you want to modify a regular variable to be passed to a function, then you need to pass its address to the function, thus the function should take a pointer type. So just use the pointer notation, i.e int *p as opposed to int p[], even though, they are equivalent as function parameters.
Your code should look like this:
#include<stdio.h>
void swap(int *x, int *y);
int main(void)
{
int x, y;
x = 1;
y = 2;
swap(&x, &y);
printf("%d = x \n %d = y", x, y);
}
void swap(int *x, int *y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}

Confused between call by ref and call by value in my code

Just started C this year in my uni and I'm confused whether my function call is by reference or value.
I created an empty array in main called freq_array and this is passed as an argument when the function frequency is called. So since after the func call, the empty array will now contain values, this is considered call by reference? I read in other websites that call by reference uses pointers so I'm slightly confused. Thank you.
void frequency(int[]); //prototype
frequency(freq_array); //func call
void frequency(int fr[arraysize]) //arraysize = 18
{
int n;
for (n=0; n<10; n++)
{
fr[n]= 100 * (n + 1); //goes from 100Hz - 1000Hz
}
for (n=10; n<18; n++) //goes from 2000Hz - 9000Hz
{
fr[n]= 1000 * (n - 8);
}
}
In theory, C only has "pass by value". However, when you use an array as parameter to a function, it gets adjusted ("decays") into a pointer to the first element.
Therefore void frequency(int fr[arraysize]) is completely equivalent to void frequency(int* fr). The compiler will replace the former with the latter "behind the lines".
So you can regard this as the array getting passed by reference, but the pointer itself, pointing at the first element, getting passed by value.
For arguments, you can't pass arrays only pointers. When the compiler sees the argument int fr[arraysize] it will treat is as int *fr.
When you do the call
frequency(freq_array);
the array decays to a pointer to its first element. The above call is equal to
frequency(&freq_array[0]);
And C doesn't have pass by reference at all. The pointer will be passed by value.
However using pointers you can emulate pass by reference. For example
void emulate_pass_by_reference(int *a)
{
*a = 10; // Use dereference to access the memory that the pointer a is pointing to
}
int main(void)
{
int b = 5;
printf("Before call: b = %d\n", b); // Will print that b is 5
emulate_pass_by_reference(&b); // Pass a pointer to the variable b
printf("After call: b = %d\n", b); // Will print that b is 10
}
Now, it's important to know that the pointer itself (&b) will be passed by value.

What is byValue and byReference argument passing In C? [duplicate]

This question already has answers here:
What's the difference between passing by reference vs. passing by value?
(18 answers)
Closed 9 years ago.
I dont understand what this means. If I were to try and guess I'd say byValue argument passing is when you pass an argument based on the value of an variable, so I'm thinking:
if (a == 1){
PassAnArgumentOrSomething()
}
However that is probably wrong :/
As for byReference, I have no idea.
If anyone can help me out that be awesome of you :)
With the exception of arrays and functions (see below), C always passes arguments `by value': a copy of the value of each argument is passed to the function; the function cannot modify the actual argument passed to it:
void foo(int j) {
j = 0; /* modifies the copy of the argument received by the function */
}
int main(void) {
int k=10;
foo(k);
/* k still equals 10 */
}
If you do want a function to modify its argument you can obtain the desired effect using pointer arguments instead:
void foo(int *j) {
*j = 0;
}
int main(void) {
int k=10;
foo(&k);
/* k now equals 0 */
}
This is sometimes known as `pass by reference' in other languages.
There is no pass by reference in c language
Passing by value: means that you are creating a temporary copy of the variable and sending to the parameter.
Passing by reference(no such concept in c language): means that you are just giving another name to the original variable while calling and no temporary copy of the variable is being created.
Calling by value:
int foo(int temp)
{
/.../
}
int main()
{
int x;
foo(x); /* here a temporary copy of the 'x' is created and sent to the foo function.*/
}
Calling by reference(no such concept in c language)
int foo(int& temp)
{
/.../
}
int main()
{
int x;
foo(x); /* here no temporary copy of 'x' is being created rather the variable *temp* in the calling function is just another name of the variable a in the main function*/
}
Passing an argument by value means you are passing a copy:
void f(int x)
{
x = 7;
// x is 7 here, but we only changed our local copy
}
void g()
{
int y = 3;
f(y);
// y is still 3 here!
}
Passing an argument by reference means you are not passing a copy, but instead passing some way of referencing the original variable. In C, all arguments are pass by value, but what is typically done to get the same effect as passing by reference is to pass a pointer:
void f(int *x_ptr) { *x_ptr = 7; }
void g()
{
int y = 3;
f(&y);
// y is 7 here
}
Arrays are passed in such a way that it appears similar to pass-by-reference, however what is actually happening is more complicated. For example:
void f(int a[]) { a[0] = 7; }
void g()
{
int b[3] = {1,2,3};
f(b);
// b[0] is 7 here! looks like it was passed by reference.
}
What is actually happening here is that the array b is implicitly converted to a pointer to the first element (this is known as decay). The int a[] notation for the parameter to f is actually syntactic sugar for a pointer. The above code is equivalent to:
void f(int *a) { a[0] = 7; }
void g()
{
int b[3] = {1,2,3};
f(&b[0]);
// b[0] is 7 here
}
Passing by value is passing the value itself; it makes a copy of the value, and any changes you make in the new function are NOT saved to the original variable:
void foo(int num)
{
num = 5; // Does not save to the original variable that was passed when foo was called
...
}
Passing by reference is passing the location of the variable; it allows the new function to directly edit the original variable:
void bar(int * num)
{
*num = 5; // Changes the variable in the original function
...
}
in-depth explanation
whenever a program loads, it gets a memory area so called address space which gets divided into various regions
code/text : contains the statements of program (collections of statements).
global : contains the global variable if any.
constant : used for constant or literal storage.
heap : used for dynamic memory need.
stack : function used its for variable.
consider a function so defined as
void doSomething(int x)
{
x++;
}//end of function
is called as doSomething(5) or doSomething(y) in another function or main function .
here
x is local variable to function "doSomething". It gets its home (memory location) somewhere in stack region.
When doSomething(5) is called 5 gets copied to x's memory or doSomething(y) is called value/content of y (different memory location) gets copied to x's memory. Whatever operations applied on x, will not affect y 's content/value at all. Since its memory location is different.
Whenever execution flow reachs at end of function x dies/gets destroyed. Whatever value of x is not accessible/available. In short, update is lost and y is unaffected (Change is not reflected).
This is what so called Call by Value
Now
Consider an another function so defined as
void doSomething(int *x)
{
(*x)++;
}
is called as doSomething(&y)
here x is called pointer (conceptually called reference*).It will also gets home somewhere in stack region
When doSomething(&y) is called address of y gets copied to x's location block. Since this x is special variable so called pointer that holds address and it is said that x refers/points to y.
When (*x)++ is applied, here * is indirection operator which will bring whom x refer to the context ie. (*x)++ will indirectly change the value of y by 1. Nothing will happen to x's value itself.
Whenever execution flow reach at end of function *x dies/gets destroyed as expected but this time change is made to y (indirectly) which is still alive somewhere in stack region (change is reflected).
Also not that this time doSomething(&5) or doSomething(any literal) is not possible because it's illegal to get address of any literal.
This is what so called Call by Reference/Call by Pointer.
note that Call by Reference has another meaning in C++ but conceptually remains same.
Let's look at the "calling" of functions first.
In C, the arguments to a function are typically "by value". Below, after calling sqrt(x), the value x is not changed for sqrt() received a copy of the value x, thus never gaining an ability to affect x.
y = sqrt(x);
// x did not change
printf("%f is the square root of %f\n", y, x);
Array parameters to a function appear to be "by reference". After fgets() is called, buf is expected to be altered. fgets() did not receive a copy of, but a "reference" to the char array. Thus fgets() could affect the contents of the array.
char buf[80] = { 0 }; // array 80 of char
printf("Before <%s>\n", buf); // "<>"
fgets(buf, sizeof buf, stdin);
printf("After <%s>\n", buf); // "<Hello World!>"
Let's now look at the "receiving" part: the function.
Function parameters of type double, int, struct types are received by value. The value of f here is the copy of the x above. Any changes made to f do not affect the x in the calling code.
double sqrt(double f) {
double y;
... // lots of code
return y;
}
Now comes the tricky bit and this is where there is lots of discussion in C.
The parameter s in fgets() below was not assigned the buf above (array 80 of char), instead s was assigned the pointer type derived from buf: address of the first element of an buf. By knowing the address of the array elements of buf (via s), fgets() affects what was printed above.
char *fgets(char * restrict s, int n, FILE * restrict stream) {
// code
s[i] = ThisAndThat();
// code
return s;
}
Let's now see how fgets() otherwise might be called:
char *p = malloc(80);
*p = '\0';
printf("Before <%s>\n", p); // "<>"
fgets(p, 80, stdin);
printf("After <%s>\n", p); // "<Hello World!>"
In this 2nd example, p is a "pointer to char". It is passed by value to fgets(). fgets() received, via s, a copy of p.
The central idea: fgets() does not know if it received an "address of the first element of an array" or a copy of a "pointer to char". In both cases, it treats s as a "pointer to char".
Let's assume fgets() did the following. Before s being changed, it affects the data pointed to by s. Then s, the pointer, changed. s is a local variable and this assignment does not change the calling routines variables buf nor p.
char *fgets(char * restrict s, int n, FILE * restrict stream) {
// lots of code
s[0] = '\0';
// more code
s = NULL;
return s;
}
Note: There are other issues such as passing functions as parameters and encapsulating arrays in structures to consider.

Passing an Array by reference in C

I'm new to C and I have a doubt.
Since C functions create local copies of it's arguments, I'm wondering why the following code works as expected:
void function(int array[]){
array[0] = 4;
array[1] = 5;
array[2] = 6;
}
int main(){
int array[] = {1,2,3};
function(array);
printf("%d %d %d",array[0],array[1],array[2]);
return 0;
}
With the line output being 4 5 6.
Why does this work while the following doesn't?
void function(int integer){
integer = 2;
}
int main(){
int integer = 1;
function(integer);
printf("%d",integer);
return 0;
}
The output is just 1 in this case.
Short version: Why can functions modify the values of their parent variables if they are passed as array?
Thank you all!
This is caused by the fact that arrays tend to decay into pointers.
int a[] = { 1, 2, 3 };
int* p = a; // valid: p is now the address of a[0]
a = p; // NOT valid.
printf("a = %p\n", a);
printf("p = %p\n", p); // prints same address as a
a and p will print the same value.
Contrary to what others have said, a is not a pointer, it can simply decay to one. http://c-faq.com/aryptr/aryptrequiv.html
In your first function() what gets passed is the address of the array's first element, and the function body dereferences that. Infact, the compiler is treating the function prototype as this:
void function(int* array /*you wrote int array[]*/){
array[0] = 4;
array[1] = 5;
array[2] = 6;
}
function(&array[0]);
This has to happen because you said "array of unknown size" (int array[]). The compiler could not guarantee to deduce the amount of stack required to pass by value, so it decays to a pointer.
---- Edit ----
Lets combine both your examples and use more distinctive names to make things clearer.
#include <stdio.h>
void func1(int dynArray[]) {
printf("func1: dynArray = %p, &dynArray[0] = %p, dynArray[0] = %d\n",
dynArray, &dynArray[0], dynArray[0]);
}
void func2(int* intPtr) {
printf("func2: intPtr = %p, &intPtr[0] = %p, intPtr[0] = %d\n",
intPtr, &intPtr[0], intPtr[0]);
}
void func3(int intVal) {
printf("func3: intVal = %d, &intValue = %p\n",
intVal, &intVal);
}
int main() {
int mainArray[3] = { 1, 2, 3 };
int mainInt = 10;
printf("mainArray = %p, &mainArray[0] = %p, mainArray[0] = %d\n",
mainArray, &mainArray, mainArray[0]);
func1(mainArray);
func2(mainArray);
printf("mainInt = %d, &mainInt = %p\n",
mainInt, &mainInt);
func3(mainInt);
return 0;
}
Live demo at ideone: http://ideone.com/P8C1f4
mainArray = 0xbf806ad4, &mainArray[0] = 0xbf806ad4, mainArray[0] = 1
func1: dynArray = 0xbf806ad4, &dynArray[0] = 0xbf806ad4, dynArray[0] = 1
func2: intPtr = 0xbf806ad4, &intPtr[0] = 0xbf806ad4, intPtr[0] = 1
mainInt = 10, &mainInt = 0xbf806acc
func3: intVal = 10, &intValue = 0xbf806ad0
In func1 and func2 "dynArray" and "intPtr" are local variables, but they are pointer variables into which they receive the address of "mainArray" from main.
This behavior is specific to arrays. If you were to put the array inside a struct, then you would be able to pass it by value.
An array passed to a function is converted to a pointer. When you pass a pointer as argument to a function, you simply give the address of the variable in the memory. So when you modify the value of the cell of the array, you edit the value under the address given to the function.
When you pass a simple integer to a function, the integer is copied in the stack, when you modify the integer within the function, you modify the copy of the integer, not the original.
Reminder of the different kinds of memory in C
In C, we can use three types of memory :
the stack, used for local variables and functions calls: when we create a variable in main(), we use the stack to store the variable, and when a function is called, the parameters given to the method are register in the stack. When we exit a function, we "pop" these parameters to return to the original state, with the used variable before the call of the function. (anecdote: a stackoverflow is when we hack the stack to use previous variables in a function without passing it as parameters)
the heap which corresponds to the dynamicly allocated memory: when we need large amount of data, we use this heap because the stack is limited to a few megabytes.
the code where the program instructions are stored
In the case of this array passed by a function, which is a pointer (address to an other variable), it is stored in the stack, when we call the function, we copy the pointer in the stack.
In the case of the integer, it is also stored in the stack, when we call the function, we copy the integer.
If we want to modify the integer, we can pass the address of the integer to modify the value under the pointer, like this:
void function(int *integer)
{
*integer = 2;
}
int main()
{
int integer = 1;
function(&integer);
printf("%d", integer);
return 0;
}
There is a difference between 'pass by reference' and 'pass by value'
Pass by reference leads to a location in the memory where pass by value passes the value directly, an array variable is always an refference, so it points to a location in the memory. Integers will pass by value by default
In the first code, you are passing the address of the array pointing to the top element in the array. So, when you modify the value in the function and return to the main function you are still accessing the same array which is in the same address. This is called pass by reference.
However, in the second case, the value of the integer is copied from the main function to the called function. In other words, the two integers are in different address in the memory. So modifying one does not modify the other.
The array name is a pointer to the first element in the array. In the first code sample you have passed a pointer to the memory location containing the first array element. In the second code sample you have passed an integer by value so it has nothing to do with the local variable named "integer"
check that link
Pass by reference and pass by value
Pass by Reference / Value in C++

Double pointers are also sometimes employed to pass pointers to functions by reference

" Double pointers are also sometimes employed to pass pointers to functions by reference "
can somebody can explain me the above statement, what exactly does point to function by reference means ?
I believe this example makes it clearer :
//Double pointer is taken as argument
void allocate(int** p, int n)
{
//Change the value of *p, this modification is available outside the function
*p = (int*)malloc(sizeof(int) * n);
}
int main()
{
int* p = NULL;
//Pass the address of the pointer
allocate(&p,1);
//The pointer has been modified to point to proper memory location
//Hence this statement will work
*p=10;
//Free the memory allocated
free(p);
return 0;
}
It means that you have a function that takes a pointer pointer (type int ** for example). This allows you to modify the pointer (what data it is pointing to) much in the way passing a pointer by reference would allow.
void change (int *p) {*p = 7;}
void Really_Change (int **pp) {*pp = null;}
int p = 1;
int *pp = &p;
// now, pp is pointing to p. Let's say it has address 0x10;
// this makes a copy of the address of p. The value of &p is still 0x10 (points to p).
// but, it uses that address to change p to 7.
change(&p);
printf("%d\n", p); // prints 7;
// this call gets the address of pp. It can change pp's value
// much like p was changed above.
Really_Change(&pp);
// pp has been set to null, much like p was set to 7.
printf("%d\n", *pp); // error dereference null. Ka-BOOM!!!
So, in the same way that you can pass a pointer to an int and change the value, you can pass a pointer to a pointer and change its value (which changes what it points to.)
I'll try to explain with both code and plain english :). The explanation may get long, but it will be worth the while.
Suppose we have a program, running its main() function, and we make a call to another function that takes an int parameter.
Conceptually, When you pass a variable as a parameter to a function, you can do so in (roughly speaking) two ways: by value, or by reference.
"By value" means giving the function a copy of your variable. The function will receive its "content" (value), but it won't be able to change the actual variable outside its own body of code, because it was only given a copy.
"By reference", on the other hand, means giving the function the actual memory address of our variable. Using that, the function can find out the variable's value, but it can also go to that specified address and modify the variable's content.
In our C program, "by value" means passing a copy of the int (just taking int as argument), and "by reference" means passing a pointer to it.
Let's see a small code example:
void foo(int n) {
n = 10;
printf("%d\n", n);
}
int main() {
int n = 5;
foo(n);
printf("%d\n", n);
return 0;
}
What will the output of this program be? 10 10? Nope. 10 5! Because we passed a copy of the int, by value and not by reference, foo() only modified the number stored in its copy, unable to reach main()'s copy.
Now, if we do it this way:
void foo(int* n) {
*n = 10;
printf("%d\n", *n);
}
int main() {
int n = 5;
foo(&n);
printf("%d\n", n);
return 0;
}
This time we gave foo() our integer by reference: it's actual memory address. foo() has full power to modify it by accessing it's position in memory, foo() and main() are working with the same copy, and so the output will be 10 10.
As you see, a pointer is a referece,... but also a numerical position in memory. It's similar to an int, only the number contained inside is interpreted differently. Think of it this way: when we pass our int by reference, we're passing an int pointer by value!. So the same by value/by reference logic can be applied to pointers, even though they already are references.
If our actual variable was not an int, but an int reference (pointer), and we wanted main() and foo() to share the same copy of that reference so that foo() can modifiy it, what would we do? Why of course, we'd need a reference to our reference! A pointer to a pointer. That is:
int n; /* integer */
int* n; /* integer reference(pointer). Stores an int's position in memory */
int** n; /* reference to integer reference, or double pointer.
Stores int*'s memory address so we can pass int*s by reference. */
I hope this was useful.

Resources