Functions and Integer Double Dimension Array
In this section, you are going to learn
What are the calling conventions of integer double dimension array ?
Call by Value
Call by Reference
Revisit Basics : Basics of Integer Double Dimension Array
Topics in this section,
int array_name[Row][Column];
Consider a integer double dimension array
int a[3][4];
Let us answer few basic questions in this array
If fun(x)
is the function call, then fun(typeof(x))
is the prototype / definition
Function Call |
Function Definition |
Observations |
---|---|---|
fun(a[0][0]) |
void fun(int x) {} |
|
fun(a[1][0]) |
void fun(int x) {} |
|
fun(a[2][0]) |
void fun(int x) {} |
|
fun(&a[0][0]) |
void fun(int *p) { } |
|
fun(&a[1][0]) |
void fun(int *p) { } |
|
fun(&a[2][0]) |
void fun(int *p) { } |
|
fun(**a) |
void fun(int x) {} |
|
fun(*(*(a + 1) + 0)) |
void fun(int x) {} |
|
fun(*(*(a + 2) + 0)) |
void fun(int x) {} |
|
fun(a[0]) |
void fun(int *p) { } |
|
fun(a[1]) |
void fun(int *p) { } |
|
fun(a[2]) |
void fun(int *p) { } |
|
fun(&a[0]) |
void fun(int (*p)[4]) { } |
|
fun(&a[1]) |
void fun(int (*p)[4]) { } |
|
fun(&a[2]) |
void fun(int (*p)[4]) { } |
|
fun(*a) |
void fun(int *p) { } |
|
fun(*(a + 1)) |
void fun(int *p) { } |
|
fun(*(a + 2)) |
void fun(int *p) { } |
|
fun(a) |
void fun(int (*p)[4]) { } |
|
fun(a + 1) |
void fun(int (*p)[4]) { } |
|
fun(a + 2) |
void fun(int (*p)[4]) { } |
|
fun(&a) |
void fun(int (*p)[3][4]) { } |
|
Let us understand the reason behind above prototypes !
If Declaration has two dereference operators, and
Expression has two dereference operators [] [], and
Expression does not have
&
then it is call by value
If Declaration has two dereference operators, and
Expression has two dereference operators * *, and
Expression does not have
&
then it is call by value
If Declaration has two dereference operators, and
Expression has two dereference operators * [ ], and
Expression does not have
&
then it is call by value
Let us look at examples
Step 1 : Consider an array
int a[3][4] = {
{1, 2, 3, 4},
{10, 20, 30, 40},
{100, 200, 300, 400}
};
Condition 1 : Declaration has TWO dereference operators [ ] and [ ]
Step 2 : Consider an expression
a[1][1]
Condition 2 : Expression has TWO dereference operators [ ] and [ ]
Note : [ ]
and *
are dereference operators
Condition 3 : Expression DOES NOT have &
operator
Hence a[1][1]
is Call By Value
Step 1 : Consider an array
int a[3][4] = {
{1, 2, 3, 4},
{10, 20, 30, 40},
{100, 200, 300, 400}
};
Condition 1 : Declaration has TWO dereference operators [ ] and [ ]
Step 2 : Consider an expression
**a
Condition 2 : Expression has TWO dereference operators * and *
Note : [ ]
and *
are dereference operators
Condition 3 : Expression DOES NOT have &
operator
Hence **a
is Call By Value
If Declaration has two dereference operators, and
Expression has two dereference operators [] [] or * * or [] *, and
Expression has &
then it is call by reference
Example : &a[0][0]
If Declaration has two dereference operators, and
Expression has one dereference operator [ ] or *, and
then it is call by reference
Example : &a[0], a[0], *a
If Declaration has two dereference operators, and
Expression has zero dereference operators, and
then it is call by reference
Example : a, &a, a + 1, a + 2
Step 1 : Consider an array
int a[3][4] = {
{1, 2, 3, 4},
{10, 20, 30, 40},
{100, 200, 300, 400}
};
Condition 1 : Declaration has TWO dereference operators [ ] and [ ]
Step 2 : Consider an expression
&a[1][1]
Condition 2 : Expression has TWO dereference operators * and *
Note : [ ]
and *
are dereference operators
Condition 3 : Expression has &
operator
Hence &a[1][1]
is Call By Reference
Step 1 : Consider an array
int a[3][4] = {
{1, 2, 3, 4},
{10, 20, 30, 40},
{100, 200, 300, 400}
};
Condition 1 : Declaration has TWO dereference operators [ ] and [ ]
Step 2 : Consider an expression
a[1]
Condition 2 : Expression has ONE dereference operators
Note : [ ]
and *
are dereference operators
Condition 3 : Expression DOES NOT have &
operator
Hence a[1]
is Call By Reference
Let us look at examples of Call by Value
Step 1 : Consider a two dimensional array
int a[3][4] = {
{1, 2, 3, 4},
{10, 20, 30, 40},
{100, 200, 300, 400}
};
Step 2 : Pass a[0][0], a[1][0], a[1][1] to a function
fun
fun(a[0][0]);
fun(a[1][0]);
fun(a[1][1]);
Step 3 : Define function
fun
void fun(int c)
{
printf("c = %d\n", c);
c = 99;
}
Step 4 : Note that it is call by Value for below reason
Condition 1 : Declaration has TWO dereference operators [ ] and [ ]
Condition 2 : Expression has TWO dereference operators [ ] and [ ]
Condition 3 : Expression DOES NOT have &
operator
Means changing value of integer inside function DOES NOT affect value of integer in Caller !
See full program below
#include <stdio.h>
void fun(int c)
{
c = 99;
}
int main(void)
{
int a[3][4] = {
{1, 2, 3, 4},
{10, 20, 30, 40},
{100, 200, 300, 400}
};
printf("----- Before call by value -----\n");
printf("a[0][0] = %d\n", a[0][0]);
printf("a[1][0] = %d\n", a[1][0]);
printf("a[1][1] = %d\n", a[1][1]);
fun(a[0][0]);
fun(a[1][0]);
fun(a[1][1]);
printf("----- After call by value -----\n");
printf("a[0][0] = %d\n", a[0][0]);
printf("a[1][0] = %d\n", a[1][0]);
printf("a[1][1] = %d\n", a[1][1]);
return 0;
}
Output is as below
----- Before call by value -----
a[0][0] = 1
a[1][0] = 10
a[1][1] = 20
----- After call by value -----
a[0][0] = 1
a[1][0] = 10
a[1][1] = 20
Step 1 : Consider a two dimensional array
int a[3][4] = {
{1, 2, 3, 4},
{10, 20, 30, 40},
{100, 200, 300, 400}
};
Step 2 : Pass **a, *(*(a + 1) + 0), *(*(a + 1) + 1) to a function
fun
fun( **a );
fun( *(*(a + 1) + 0) );
fun( *(*(a + 1) + 1) );
Step 3 : Define function
fun
void fun(int c)
{
c = 99;
}
Step 4 : Note that it is call by Value for below reason
Condition 1 : Declaration has TWO dereference operators [ ] and [ ]
Condition 2 : Expression has TWO dereference operators * and *
Condition 3 : Expression DOES NOT have &
operator
Means changing value of integer inside function DOES NOT affect value of integer in Caller !
See full program below
#include <stdio.h>
void fun(int c)
{
c = 99;
}
int main(void)
{
int a[3][4] = {
{1, 2, 3, 4},
{10, 20, 30, 40},
{100, 200, 300, 400}
};
printf("----- Before call by value -----\n");
printf("**a = %d\n", **a);
printf("*(*(a + 1) + 0) = %d\n", *(*(a + 1) + 0) );
printf("*(*(a + 1) + 1) = %d\n", *(*(a + 1) + 1) );
fun( **a );
fun( *(*(a + 1) + 0) );
fun( *(*(a + 1) + 1) );
printf("----- After call by value -----\n");
printf("**a = %d\n", **a);
printf("*(*(a + 1) + 0) = %d\n", *(*(a + 1) + 0) );
printf("*(*(a + 1) + 1) = %d\n", *(*(a + 1) + 1) );
return 0;
}
Output is as below
----- Before call by value -----
**a = 1
*(*(a + 1) + 0) = 10
*(*(a + 1) + 1) = 20
----- After call by value -----
**a = 1
*(*(a + 1) + 0) = 10
*(*(a + 1) + 1) = 20
Let us look at examples of Call by Reference
Step 1 : Consider a two dimensional array
int a[3][4] = {
{1, 2, 3, 4},
{10, 20, 30, 40},
{100, 200, 300, 400}
};
There are 3 single dimension arrays in int a[3][4]
a[0]
a[1]
a[2]
a[0] is also equal to *a
a[1] is also equal to *(a + 1)
a[2] is also equal to *(a + 2)
a[0] is also equal to &a[0][0]
a[1] is also equal to &a[1][0]
a[2] is also equal to &a[2][0]
Step 2.1 : Method 1 : Pass &a[0][0], &a[1][0], &a[2][0] to a function
fun
fun( &a[0][0] );
fun( &a[1][0] );
fun( &a[2][0] );
Step 2.2 : Method 2 : Pass a[0], a[1], a[2] to a function
fun
fun( a[0] );
fun( a[1] );
fun( a[2] );
Step 2.3 : Method 3 : Pass *a, *(a + 1), *(a + 2) to a function
fun
fun( *a );
fun( *(a + 1) );
fun( *(a + 2) );
Step 3.1 : Define function
fun
void fun(int *ptr)
{
}
Step 4 : Note that it is call by Reference. Means contents of single dimension array can be changed inside function
fun
void fun(int *ptr)
{
for (int i = 0; i < 4; i++)
{
printf("ptr[%d] = %d\n", i, ptr[i] );
}
}
See full program below
#include <stdio.h>
void fun(int *ptr)
{
for (int i = 0; i < 4; i++)
{
printf("ptr[%d] = %d\n", i, ptr[i] );
}
}
int main(void)
{
int a[3][4] = {
{1, 2, 3, 4},
{10, 20, 30, 40},
{100, 200, 300, 400}
};
printf("Method 1 : Access Single dimension arrays\n");
fun( &a[0][0] );
fun( &a[1][0] );
fun( &a[2][0] );
printf("Method 2 : Access Single dimension arrays\n");
fun( a[0] );
fun( a[1] );
fun( a[2] );
printf("Method 3 : Access Single dimension arrays\n");
fun( *a );
fun( *(a + 1) );
fun( *(a + 2) );
return 0;
}
Output is as below
Method 1 : Access Single dimension arrays
ptr[0] = 1
ptr[1] = 2
ptr[2] = 3
ptr[3] = 4
ptr[0] = 10
ptr[1] = 20
ptr[2] = 30
ptr[3] = 40
ptr[0] = 100
ptr[1] = 200
ptr[2] = 300
ptr[3] = 400
Method 2 : Access Single dimension arrays
ptr[0] = 1
ptr[1] = 2
ptr[2] = 3
ptr[3] = 4
ptr[0] = 10
ptr[1] = 20
ptr[2] = 30
ptr[3] = 40
ptr[0] = 100
ptr[1] = 200
ptr[2] = 300
ptr[3] = 400
Method 3 : Access Single dimension arrays
ptr[0] = 1
ptr[1] = 2
ptr[2] = 3
ptr[3] = 4
ptr[0] = 10
ptr[1] = 20
ptr[2] = 30
ptr[3] = 40
ptr[0] = 100
ptr[1] = 200
ptr[2] = 300
ptr[3] = 400
Step 1 : Consider a two dimensional array
int a[3][4] = {
{1, 2, 3, 4},
{10, 20, 30, 40},
{100, 200, 300, 400}
};
There are 3 single dimension arrays in int a[3][4]
a[0]
a[1]
a[2]
Address of single dimension arrays is simply
&a[0]
&a[1]
&a[2]
&a[0] is also equal to a
&a[1] is also equal to a + 1
&a[2] is also equal to a + 2
Step 2.1 : Method 1 : Pass address of single dimension arrays to a function
fun
fun( &a[0] );
fun( &a[1] );
fun( &a[2] );
Step 2.2 : Method 2 : Pass address of single dimension arrays to a function
fun
fun( a );
fun( a + 1 );
fun( a + 2 );
Step 3.1 : Define the function
fun
void fun(int (*ptr)[4] )
{
}
Step 3.2 : Define the function
fun
to change the contents of single dimension array integer by integer
void fun(int (*ptr)[4] )
{
(*ptr)[0] = 11;
(*ptr)[1] = 22;
(*ptr)[2] = 33;
(*ptr)[3] = 44;
}
See full program below
#include <stdio.h>
void fun(int (*ptr)[4] )
{
(*ptr)[0] = 11;
(*ptr)[1] = 22;
(*ptr)[2] = 33;
(*ptr)[3] = 44;
}
int main(void)
{
int a[3][4] = {
{1, 2, 3, 4},
{10, 20, 30, 40},
{100, 200, 300, 400}
};
printf("----- Before call by referene -----\n");
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
printf("a[%d][%d] = %d\n", i, j, a[i][j]);
}
}
//Method 1 : Access Single dimension arrays. Call by reference
fun( &a[0] );
fun( &a[1] );
fun( &a[2] );
//Method 2 : Access Single dimension arrays. Call by reference
fun( a );
fun( a + 1 );
fun( a + 2 );
printf("----- After call by referene -----\n");
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
printf("a[%d][%d] = %d\n", i, j, a[i][j]);
}
}
return 0;
}
Output is as below
----- Before call by referene -----
a[0][0] = 1
a[0][1] = 2
a[0][2] = 3
a[0][3] = 4
a[1][0] = 10
a[1][1] = 20
a[1][2] = 30
a[1][3] = 40
a[2][0] = 100
a[2][1] = 200
a[2][2] = 300
a[2][3] = 400
----- After call by referene -----
a[0][0] = 11
a[0][1] = 22
a[0][2] = 33
a[0][3] = 44
a[1][0] = 11
a[1][1] = 22
a[1][2] = 33
a[1][3] = 44
a[2][0] = 11
a[2][1] = 22
a[2][2] = 33
a[2][3] = 44
Step 1 : Consider a two dimensional array
int a[3][4] = {
{1, 2, 3, 4},
{10, 20, 30, 40},
{100, 200, 300, 400}
};
Step 2 : Pass Address of Double Dimension array to a function
fun(&a);
Step 3.1 : Define function
fun
void fun(int (*ptr)[3][4] )
{
}
Step 3.2 : Access and change individual integers inside function
fun
int data = 100;
for (int i = 0 ; i < 3; i++) {
for (int j = 0 ; j < 4; j++) {
(*ptr)[i][j] = ++data;
}
}
See full program below
#include <stdio.h>
void fun(int (*ptr)[3][4] )
{
// Change Individual integers
int data = 100;
for (int i = 0 ; i < 3; i++) {
for (int j = 0 ; j < 4; j++) {
(*ptr)[i][j] = ++data;
}
}
}
int main(void)
{
int a[3][4] = {
{1, 2, 3, 4},
{10, 20, 30, 40},
{100, 200, 300, 400}
};
printf("----- Before call by reference -----\n");
for (int i = 0 ; i < 3; i++) {
for (int j = 0 ; j < 4; j++) {
printf("a[%d][%d] = %d\n", i, j, a[i][j]);
}
}
fun(&a);
printf("----- After call by reference -----\n");
for (int i = 0 ; i < 3; i++) {
for (int j = 0 ; j < 4; j++) {
printf("a[%d][%d] = %d\n", i, j, a[i][j]);
}
}
return 0;
}
Output is as below
----- Before call by reference -----
a[0][0] = 1
a[0][1] = 2
a[0][2] = 3
a[0][3] = 4
a[1][0] = 10
a[1][1] = 20
a[1][2] = 30
a[1][3] = 40
a[2][0] = 100
a[2][1] = 200
a[2][2] = 300
a[2][3] = 400
----- After call by reference -----
a[0][0] = 101
a[0][1] = 102
a[0][2] = 103
a[0][3] = 104
a[1][0] = 105
a[1][1] = 106
a[1][2] = 107
a[1][3] = 108
a[2][0] = 109
a[2][1] = 110
a[2][2] = 111
a[2][3] = 112
Other topics of integer and functions
Current Module
Previous Module
Next Module
Other Modules