Functions and Integer Single Pointer
In this section, you are going to learn
What are the calling conventions of integer single pointer ?
Call by Value
Call by Reference
Revisit Basics : Basics of Integer Single Pointers
Topics in this section,
int *sp;
Consider a Integer Single Pointer
int *sp;
Let us answer few basic questions about integer single pointer
If fun(x)
is the function call, then fun(typeof(x))
is the prototype / definition
Function Call |
Function Definition |
Observations |
---|---|---|
fun(sp[0]) |
void fun(int x) { } |
|
fun(sp[1]) |
void fun(int x) { } |
|
fun(sp[9]) |
void fun(int x) { } |
|
fun(&sp[0]) |
void fun(int *p) { } |
|
fun(&sp[1]) |
void fun(int *p) { } |
|
fun(&sp[9]) |
void fun(int *p) { } |
|
fun(*sp) |
void fun(int x) { } |
|
fun(*(sp + 1)) |
void fun(int x) { } |
|
fun(*(sp + 9)) |
void fun(int x) { } |
|
fun(sp) |
void fun(int *p) { } |
|
fun(sp + 1) |
void fun(int *p) { } |
|
fun(sp + 9) |
void fun(int *p) { } |
|
fun(&sp) |
void fun(int **p) { } |
|
If Declaration has ONE dereference operator, and
Expression has ONE dereference operator [], and
Expression does not have
&
then it is call by value
If Declaration has ONE dereference operators, and
Expression has ONE dereference operator *, and
Expression does not have
&
then it is call by value
If Declaration has ONE dereference operator, and
Expression has ONE dereference operators [] or *, and
Expression has ONE &
then it is call by reference
Example : &sp[0]
If Declaration has ONE dereference operator, and
Expression has ZERO dereference operator [ ] or *, and
Expression has ZERO & operator
then it is call by reference
Example : sp + 1, sp + 4
If Declaration has ONE dereference operator, and
Expression has ZERO dereference operator [ ] or *, and
Expression has ONE & operator
then it is call by reference
Example : &sp
Let us look at examples of Call by Value
Example for Call By Value with [ ]
Step 1 : Define a integer single pointer
sp
int *sp;
Step 2 : Allocate heap memory of Bytes
sp = malloc(5 * sizeof(int));
Step 3 : Copy string to heap memory pointed to by
sp
sp[0] = 11;
sp[1] = 22;
sp[2] = 33;
sp[3] = 44;
sp[4] = 55;
Step 4 : Pass an individual integer
sp[2]
to a function. Call by Value
fun(sp[2]);
Individual heap elements can be accessed using [ ]
In this case sp[2]
is third integer in the heap
sp[2]
is fully dereferenced and there is no &
symbol in fun(sp[2])
. Hence this is Call By Value
Step 5 : Define function
fun
void fun(int x)
{
}
Step 6 : Change value of
x
inside functionfun
void fun(int x)
{
x = 100;
printf("x = %d\n", x);
}
Step 7 : Free heap memory after use
free(sp);
See the full program below
#include <stdio.h>
#include <stdlib.h>
void fun(int x)
{
x = 100;
printf("x = %d\n", x);
}
int main(void)
{
int *sp;
sp = malloc(5 * sizeof(int));
sp[0] = 11;
sp[1] = 22;
sp[2] = 33;
sp[3] = 44;
sp[4] = 55;
printf("----- Before call by value -----\n");
for (int i = 0; i < 5; i++)
{
printf("sp[%d] = %d\n", i, sp[i]);
}
fun(sp[2]);
printf("----- After call by value -----\n");
for (int i = 0; i < 5; i++)
{
printf("sp[%d] = %d\n", i, sp[i]);
}
free(sp);
return 0;
}
Output is as below
----- Before call by value -----
sp[0] = 11
sp[1] = 22
sp[2] = 33
sp[3] = 44
sp[4] = 55
x = 100
----- After call by value -----
sp[0] = 11
sp[1] = 22
sp[2] = 33
sp[3] = 44
sp[4] = 55
Changing value of x
inside function fun
DOES NOT change sp[2]
Example for Call By Value with *
Step 1 : Define a integer single pointer
sp
int *sp;
Step 2 : Allocate heap memory of Bytes
sp = malloc(5 * sizeof(int));
Step 3 : Copy string to heap memory pointed to by
sp
sp[0] = 11;
sp[1] = 22;
sp[2] = 33;
sp[3] = 44;
sp[4] = 55;
Step 4 : Pass an individual integer
*(a + 2)
to a function. Call by Value
fun( *(sp + 2) );
Individual array elements can be accessed using *
In this case *(sp + 2)
is third integer in the array
*(sp + 2)
is fully dereferenced and there is no &
symbol in fun( *(sp + 2) )
. Hence this is Call By Value
Step 5 : Define function
fun
void fun(int x)
{
}
Step 6 : Change value of
x
inside functionfun
void fun(int x)
{
x = 100;
printf("x = %d\n", x);
}
Step 7 : Free heap memory after use
free(sp);
See the full program below
#include <stdio.h>
#include <stdlib.h>
void fun(int x)
{
x = 100;
printf("x = %d\n", x);
}
int main(void)
{
int *sp;
sp = malloc(5 * sizeof(int));
sp[0] = 11;
sp[1] = 22;
sp[2] = 33;
sp[3] = 44;
sp[4] = 55;
printf("----- Before call by value -----\n");
for (int i = 0; i < 5; i++)
{
printf("sp[%d] = %d\n", i, sp[i]);
}
fun( *(sp + 2) );
printf("----- After call by value -----\n");
for (int i = 0; i < 5; i++)
{
printf("sp[%d] = %d\n", i, sp[i]);
}
free(sp);
return 0;
}
Output is as below
----- Before call by value -----
sp[0] = 11
sp[1] = 22
sp[2] = 33
sp[3] = 44
sp[4] = 55
x = 100
----- After call by value -----
sp[0] = 11
sp[1] = 22
sp[2] = 33
sp[3] = 44
sp[4] = 55
Changing value of x
inside function fun
DOES NOT change *(sp + 2)
Remember sp[2]
and *(sp + 2)
are one and the same
Let us look at examples of Call by Reference
Example for Call By Reference with &sp[ ]
Step 1 : Define a integer single pointer
sp
int *sp;
Step 2 : Allocate heap memory of Bytes
sp = malloc(5 * sizeof(int));
Step 3 : Copy string to heap memory pointed to by
sp
sp[0] = 11;
sp[1] = 22;
sp[2] = 33;
sp[3] = 44;
sp[4] = 55;
Step 4 : Pass address of an individual integer
&sp[2]
to a function. Call by Reference
fun( &sp[2] );
Address of individual heap elements can be accessed using &
In this case &sp[2]
is the address of third integer in the heap
Since we are passing address of third integer to function fun
, it is called call by reference with respect to third integer
Step 5 : Define function
fun
void fun(int *x)
{
}
Step 6 : Change value of
*x
inside functionfun
void fun(int *x)
{
*x = 100;
printf("*x = %d\n", *x);
}
Step 7 : Free heap memory after use
free(sp);
See the full program below
#include <stdio.h>
#include <stdlib.h>
void fun(int *x)
{
*x = 100;
printf("*x = %d\n", *x);
}
int main(void)
{
int *sp;
sp = malloc(5 * sizeof(int));
sp[0] = 11;
sp[1] = 22;
sp[2] = 33;
sp[3] = 44;
sp[4] = 55;
printf("----- Before call by reference -----\n");
for (int i = 0; i < 5; i++)
{
printf("sp[%d] = %d\n", i, sp[i]);
}
fun( &sp[2] );
printf("----- After call by reference -----\n");
for (int i = 0; i < 5; i++)
{
printf("sp[%d] = %d\n", i, sp[i]);
}
free(sp);
return 0;
}
Output is as below
----- Before call by reference -----
sp[0] = 11
sp[1] = 22
sp[2] = 33
sp[3] = 44
sp[4] = 55
*x = 100
----- After call by reference -----
sp[0] = 11
sp[1] = 22
sp[2] = 100
sp[3] = 44
sp[4] = 55
Changing value of *x
inside function fun
CHANGES sp[2]
in sp
Example for Call By Reference with (sp + x)
Step 1 : Define a integer single pointer
sp
int *sp;
Step 2 : Allocate heap memory of Bytes
sp = malloc(5 * sizeof(int));
Step 3 : Copy string to heap memory pointed to by
sp
sp[0] = 11;
sp[1] = 22;
sp[2] = 33;
sp[3] = 44;
sp[4] = 55;
Step 4 : Pass address of individual integer
sp + 2
to a function. Call by Reference
fun( sp + 2 );
In this case sp + 2
is the address of third integer in the heap
Since we are passing address of third integer to function fun
, it is called call by reference with respect to third integer
Step 5 : Define function
fun
void fun(int *x)
{
}
Step 6 : Change value of
*x
inside functionfun
void fun(int *x)
{
*x = 100;
printf("*x = %d\n", *x);
}
Step 7 : Free heap memory after use
free(sp);
See the full program below
#include <stdio.h>
#include <stdlib.h>
void fun(int *x)
{
*x = 100;
printf("*x = %d\n", *x);
}
int main(void)
{
int *sp;
sp = malloc(5 * sizeof(int));
sp[0] = 11;
sp[1] = 22;
sp[2] = 33;
sp[3] = 44;
sp[4] = 55;
printf("----- Before call by reference -----\n");
for (int i = 0; i < 5; i++)
{
printf("sp[%d] = %d\n", i, sp[i]);
}
fun( sp + 2 );
printf("----- After call by reference -----\n");
for (int i = 0; i < 5; i++)
{
printf("sp[%d] = %d\n", i, sp[i]);
}
free(sp);
return 0;
}
Output is as below
----- Before call by reference -----
sp[0] = 11
sp[1] = 22
sp[2] = 33
sp[3] = 44
sp[4] = 55
*x = 100
----- After call by reference -----
sp[0] = 11
sp[1] = 22
sp[2] = 100
sp[3] = 44
sp[4] = 55
Changing value of *x
inside function fun
CHANGES sp[2]
Step 1 : Define a integer single pointer
sp
int *sp;
Step 2 : Allocate heap memory of Bytes
sp = malloc(5 * sizeof(int));
Step 3 : Copy string to heap memory pointed to by
sp
sp[0] = 11;
sp[1] = 22;
sp[2] = 33;
sp[3] = 44;
sp[4] = 55;
Step 4 : Pass full array array to a function
fun( sp );
Note that we are passing starting address of array
Hence function fun
has read and write access to all Bytes of array
Step 5 : Define a function
void fun(int *x)
{
x[0] = 111;
x[1] = 222;
x[2] = 333;
x[3] = 444;
x[4] = 555;
}
function fun
has access to all integers
Step 6 : Free heap memory after use
free(sp);
See full program below
#include <stdio.h>
#include <stdlib.h>
void fun(int *x)
{
x[0] = 111;
x[1] = 222;
x[2] = 333;
x[3] = 444;
x[4] = 555;
}
int main(void)
{
int *sp;
sp = malloc(5 * sizeof(int));
sp[0] = 11;
sp[1] = 22;
sp[2] = 33;
sp[3] = 44;
sp[4] = 55;
printf("----- Before call by reference -----\n");
for (int i = 0; i < 5; i++)
{
printf("sp[%d] = %d\n", i, sp[i]);
}
fun(sp);
printf("----- After call by reference -----\n");
for (int i = 0; i < 5; i++)
{
printf("sp[%d] = %d\n", i, sp[i]);
}
free(sp);
return 0;
}
Output is as below
----- Before call by reference -----
sp[0] = 11
sp[1] = 22
sp[2] = 33
sp[3] = 44
sp[4] = 55
----- After call by reference -----
sp[0] = 111
sp[1] = 222
sp[2] = 333
sp[3] = 444
sp[4] = 555
Step 1 : Define a integer single pointer
sp
int *sp;
Step 2 : Allocate heap memory of Bytes
sp = malloc(5 * sizeof(int));
Step 3 : Copy string to heap memory pointed to by
sp
sp[0] = 11;
sp[1] = 22;
sp[2] = 33;
sp[3] = 44;
sp[4] = 55;
Step 4 : Pass full array by reference with relative addressing
fun( sp + 2 );
Note that we are passing part of the array by reference
In this case, we are passing address of 3rd integer
Hence function fun
has read and write access to Integers at indexes 2,3,4 in forward direction
Hence function fun
has read and write access to Integers 0, 1 in backward direction
Step 5 : Define a function
void fun(int *x)
{
x[-2] = 111; // Same as sp[0]
x[-1] = 222; // Same as sp[1]
x[0] = 333; // Same as sp[2]
x[1] = 444; // Same as sp[3]
x[2] = 555; // Same as sp[4]
}
Note the relative access mechanism used inside function fun
See full program below
#include <stdio.h>
#include <stdlib.h>
void fun(int *x)
{
x[-2] = 111; // Same as sp[0]
x[-1] = 222; // Same as sp[1]
x[0] = 333; // Same as sp[2]
x[1] = 444; // Same as sp[3]
x[2] = 555; // Same as sp[4]
}
int main(void)
{
int *sp;
sp = malloc(5 * sizeof(int));
sp[0] = 11;
sp[1] = 22;
sp[2] = 33;
sp[3] = 44;
sp[4] = 55;
printf("----- Before call by reference -----\n");
for (int i = 0; i < 5; i++)
{
printf("sp[%d] = %d\n", i, sp[i]);
}
fun(sp + 2);
printf("----- After call by reference -----\n");
for (int i = 0; i < 5; i++)
{
printf("sp[%d] = %d\n", i, sp[i]);
}
free(sp);
return 0;
}
Output is as below
----- Before call by reference -----
sp[0] = 11
sp[1] = 22
sp[2] = 33
sp[3] = 44
sp[4] = 55
----- After call by reference -----
sp[0] = 111
sp[1] = 222
sp[2] = 333
sp[3] = 444
sp[4] = 555
Step 1 : Define a integer single pointer
sp
int *sp;
Step 2 : Allocate heap memory of Bytes
sp = malloc(5 * sizeof(int));
Step 3 : Copy string to heap memory pointed to by
sp
sp[0] = 11;
sp[1] = 22;
sp[2] = 33;
sp[3] = 44;
sp[4] = 55;
Step 4 : Pass the address of array
sp
to functionfun
fun(&sp);
Step 5 : Define the function
fun
void fun( int **dp)
{
}
Note that int **dp
is a pointer to a integer single pointer
Step 6 : Access individual integers inside function
fun
void fun( int **dp )
{
//Change individual integers
(*dp)[0] = 111;
(*dp)[1] = 222;
(*dp)[2] = 333;
(*dp)[3] = 444;
(*dp)[4] = 555;
}
Step 8 : Free heap memory after use
free(sp);
See the full program below
#include <stdio.h>
#include <stdlib.h>
void fun( int **dp )
{
//Change individual integers
(*dp)[0] = 111;
(*dp)[1] = 222;
(*dp)[2] = 333;
(*dp)[3] = 444;
(*dp)[4] = 555;
}
int main(void)
{
int *sp;
sp = malloc(5 * sizeof(int));
sp[0] = 11;
sp[1] = 22;
sp[2] = 33;
sp[3] = 44;
sp[4] = 55;
printf("----- Before call by reference -----\n");
for (int i = 0; i < 5; i++)
{
printf("sp[%d] = %d\n", i, sp[i]);
}
fun(&sp);
printf("----- After call by reference -----\n");
for (int i = 0; i < 5; i++)
{
printf("sp[%d] = %d\n", i, sp[i]);
}
free(sp);
return 0;
}
Output is as below
----- Before call by reference -----
sp[0] = 11
sp[1] = 22
sp[2] = 33
sp[3] = 44
sp[4] = 55
----- After call by reference -----
sp[0] = 111
sp[1] = 222
sp[2] = 333
sp[3] = 444
sp[4] = 555
Other topics of integer and functions
Current Module
Previous Module
Next Module
Other Modules