Functions and Structure Single Dimension Array
In this section, you are going to learn
What are the calling conventions of structure single dimension array ?
Call by Value
Call by Reference
Revisit Basics : Basics of Structure Single Dimension Array
Topics in this section,
struct ABC {
type1 member1;
type2 member2;
type3 member3;
};
struct ABC array_name[Column];
Consider a Structure Single Dimension Array
struct ABC {
int a;
int b;
int c;
};
struct ABC x[5];
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(x[0]) |
void fun(struct ABC x) { } |
|
fun(x[1]) |
void fun(struct ABC x) { } |
|
fun(x[4]) |
void fun(struct ABC x) { } |
|
fun(&x[0]) |
void fun(struct ABC *p) { } |
|
fun(&x[1]) |
void fun(struct ABC *p) { } |
|
fun(&x[4]) |
void fun(struct ABC *p) { } |
|
fun(*x) |
void fun(struct ABC x) { } |
|
fun(*(x + 1)) |
void fun(struct ABC x) { } |
|
fun(*(x + 4)) |
void fun(struct ABC x) { } |
|
fun(x) |
void fun(struct ABC *p) { } |
|
fun(x + 1) |
void fun(struct ABC *p) { } |
|
fun(x + 4) |
void fun(struct ABC *p) { } |
|
fun(&x) |
void fun(struct ABC (*p) [4] ) { } |
|
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 : &x[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 : x + 1, x + 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 : &x
Let us look at examples of Call by Value
Example for Call By Value with [ ]
Step 1 : Define a structure array
x
struct ABC {
int a;
int b;
int c;
};
struct ABC x[5] = {
{.a = 1, .b = 2, .c = 3},
{.a = 4, .b = 5, .c = 6},
{.a = 7, .b = 8, .c = 9},
{.a = 10, .b = 11, .c = 12},
{.a = 13, .b = 14, .c = 15},
};
Step 2 : Pass an individual structure
x[2]
to a function. Call by Value
fun(x[2]);
Individual array elements can be accessed using [ ]
In this case x[2]
is third structure in the array
x[2]
is fully dereferenced and there is no &
symbol in fun(x[2])
. Hence this is Call By Value
Step 3 : Define function
fun
void fun(struct ABC x)
{
}
Step 4 : Change value of
x
inside functionfun
void fun(struct ABC x)
{
x.a = 100;
x.b = 101;
x.c = 102;
}
See the full program below
#include <stdio.h>
struct ABC {
int a;
int b;
int c;
};
void fun(struct ABC x)
{
x.a = 100;
x.b = 101;
x.c = 102;
}
int main(void)
{
struct ABC x[5] = {
{.a = 1, .b = 2, .c = 3},
{.a = 4, .b = 5, .c = 6},
{.a = 7, .b = 8, .c = 9},
{.a = 10, .b = 11, .c = 12},
{.a = 13, .b = 14, .c = 15},
};
printf("----- Before Call By Value -----\n");
printf("x[2].a = %d\n", x[2].a);
printf("x[2].b = %d\n", x[2].b);
printf("x[2].c = %d\n", x[2].c);
fun(x[2]);
printf("----- After Call By Value -----\n");
printf("x[2].a = %d\n", x[2].a);
printf("x[2].b = %d\n", x[2].b);
printf("x[2].c = %d\n", x[2].c);
return 0;
}
Output is as below
----- Before Call By Value -----
x[2].a = 7
x[2].b = 8
x[2].c = 9
----- After Call By Value -----
x[2].a = 7
x[2].b = 8
x[2].c = 9
Changing value of x
inside function fun
DOES NOT change a[2]
in array a
Example for Call By Value with *
Step 1 : Define a structure array
x
struct ABC {
int a;
int b;
int c;
};
struct ABC x[5] = {
{.a = 1, .b = 2, .c = 3},
{.a = 4, .b = 5, .c = 6},
{.a = 7, .b = 8, .c = 9},
{.a = 10, .b = 11, .c = 12},
{.a = 13, .b = 14, .c = 15},
};
Step 2 : Pass an individual structure
*(x + 2)
to a function. Call by Value
fun( *(x + 2) );
Individual array elements can be accessed using *
In this case *(x + 2)
is third structure in the array
*(x + 2)
is fully dereferenced and there is no &
symbol in fun( *(x + 2) )
. Hence this is Call By Value
Step 3 : Define function
fun
void fun(struct ABC x)
{
}
Step 4 : Change value of
x
inside functionfun
void fun(struct ABC x)
{
x.a = 100;
x.b = 101;
x.c = 102;
}
See the full program below
#include <stdio.h>
struct ABC {
int a;
int b;
int c;
};
void fun(struct ABC x)
{
x.a = 100;
x.b = 101;
x.c = 102;
}
int main(void)
{
struct ABC x[5] = {
{.a = 1, .b = 2, .c = 3},
{.a = 4, .b = 5, .c = 6},
{.a = 7, .b = 8, .c = 9},
{.a = 10, .b = 11, .c = 12},
{.a = 13, .b = 14, .c = 15},
};
printf("----- Before Call By Value -----\n");
printf(" (*(x + 2)).a = %d\n", (*(x + 2)).a );
printf(" (*(x + 2)).b = %d\n", (*(x + 2)).b );
printf(" (*(x + 2)).c = %d\n", (*(x + 2)).c );
fun( *(x + 2) );
printf("----- After Call By Value -----\n");
printf(" (*(x + 2)).a = %d\n", (*(x + 2)).a );
printf(" (*(x + 2)).b = %d\n", (*(x + 2)).b );
printf(" (*(x + 2)).c = %d\n", (*(x + 2)).c );
return 0;
}
Output is as below
----- Before Call By Value -----
(*(x + 2)).a = 7
(*(x + 2)).b = 8
(*(x + 2)).c = 9
----- After Call By Value -----
(*(x + 2)).a = 7
(*(x + 2)).b = 8
(*(x + 2)).c = 9
Changing value of x
inside function fun
DOES NOT change *(x + 2)
in array x
Remember x[2]
and *(x + 2)
are one and the same
Let us look at examples of Call by Reference
Example for Call By Reference with &x[ ]
Step 1 : Define a structure array
x
struct ABC {
int a;
int b;
int c;
};
struct ABC x[5] = {
{.a = 1, .b = 2, .c = 3},
{.a = 4, .b = 5, .c = 6},
{.a = 7, .b = 8, .c = 9},
{.a = 10, .b = 11, .c = 12},
{.a = 13, .b = 14, .c = 15},
};
Step 2 : Pass address of an individual structure
&x[2]
to a function. Call by Reference
fun( &x[2] );
Address of individual array elements can be accessed using &
In this case &x[2]
is the address of third structure in the array
Since we are passing address of third structure to function fun
, it is called call by reference with respect to third structure
Step 3 : Define function
fun
void fun(struct ABC *x)
{
}
Step 4 : Change value of
*x
inside functionfun
void fun(struct ABC *x)
{
x->a = 777;
x->b = 888;
x->c = 999;
}
See the full program below
#include <stdio.h>
struct ABC {
int a;
int b;
int c;
};
void fun(struct ABC *x)
{
x->a = 777;
x->b = 888;
x->c = 999;
}
int main(void)
{
struct ABC x[5] = {
{.a = 1, .b = 2, .c = 3},
{.a = 4, .b = 5, .c = 6},
{.a = 7, .b = 8, .c = 9},
{.a = 10, .b = 11, .c = 12},
{.a = 13, .b = 14, .c = 15},
};
printf("----- Before Call By Reference -----\n");
printf("x[2].a = %d\n", x[2].a);
printf("x[2].b = %d\n", x[2].b);
printf("x[2].c = %d\n", x[2].c);
fun( &x[2] );
printf("----- After Call By Reference -----\n");
printf("x[2].a = %d\n", x[2].a);
printf("x[2].b = %d\n", x[2].b);
printf("x[2].c = %d\n", x[2].c);
return 0;
}
Output is as below
----- Before Call By Reference -----
x[2].a = 7
x[2].b = 8
x[2].c = 9
----- After Call By Reference -----
x[2].a = 777
x[2].b = 888
x[2].c = 999
Changing value of *x
inside function fun
CHANGES x[2]
in array x
Example for Call By Reference with (x + n)
Step 1 : Define a structure array
x
struct ABC {
int a;
int b;
int c;
};
struct ABC x[5] = {
{.a = 1, .b = 2, .c = 3},
{.a = 4, .b = 5, .c = 6},
{.a = 7, .b = 8, .c = 9},
{.a = 10, .b = 11, .c = 12},
{.a = 13, .b = 14, .c = 15},
};
Step 2 : Pass address of individual structure
x + 2
to a function. Call by Reference
fun( x + 2 );
In this case x + 2
is the address of third structure in the array
Since we are passing address of third structure to function fun
, it is called call by reference with respect to third structure
Step 3 : Define function
fun
void fun(struct ABC *x)
{
}
Step 4 : Change value of
*x
inside functionfun
void fun(struct ABC *x)
{
x->a = 777;
x->b = 888;
x->c = 999;
}
See the full program below
#include <stdio.h>
struct ABC {
int a;
int b;
int c;
};
void fun(struct ABC *x)
{
x->a = 777;
x->b = 888;
x->c = 999;
}
int main(void)
{
struct ABC x[5] = {
{.a = 1, .b = 2, .c = 3},
{.a = 4, .b = 5, .c = 6},
{.a = 7, .b = 8, .c = 9},
{.a = 10, .b = 11, .c = 12},
{.a = 13, .b = 14, .c = 15},
};
printf("----- Before Call By Reference -----\n");
printf("x[2].a = %d\n", x[2].a);
printf("x[2].b = %d\n", x[2].b);
printf("x[2].c = %d\n", x[2].c);
fun( x + 2 );
printf("----- After Call By Reference -----\n");
printf("x[2].a = %d\n", x[2].a);
printf("x[2].b = %d\n", x[2].b);
printf("x[2].c = %d\n", x[2].c);
return 0;
}
Output is as below
----- Before Call By Reference -----
x[2].a = 7
x[2].b = 8
x[2].c = 9
----- After Call By Reference -----
x[2].a = 777
x[2].b = 888
x[2].c = 999
Changing value of *x
inside function fun
CHANGES x[2]
in array x
Step 1 : Consider a structure array
struct ABC {
int a;
int b;
int c;
};
struct ABC x[5] = {
{.a = 1, .b = 2, .c = 3},
{.a = 4, .b = 5, .c = 6},
{.a = 7, .b = 8, .c = 9},
{.a = 10, .b = 11, .c = 12},
{.a = 13, .b = 14, .c = 15},
};
Step 2 : Pass full array array to a function
fun( x );
Note that we are passing starting address of array
Hence function fun
has read and write access to all Bytes of array
Step 3 : Define a function
void fun(struct ABC *x)
{
for (int i = 0; i < 5; i++)
{
x[i].a = 777;
x[i].b = 888;
x[i].c = 999;
}
}
function fun
has access to all structures
See full program below
#include <stdio.h>
struct ABC {
int a;
int b;
int c;
};
void fun(struct ABC *x)
{
for (int i = 0; i < 5; i++)
{
x[i].a = 777;
x[i].b = 888;
x[i].c = 999;
}
}
int main(void)
{
struct ABC x[5] = {
{.a = 1, .b = 2, .c = 3},
{.a = 4, .b = 5, .c = 6},
{.a = 7, .b = 8, .c = 9},
{.a = 10, .b = 11, .c = 12},
{.a = 13, .b = 14, .c = 15},
};
printf("----- Before Call By Reference -----\n");
for (int i = 0; i < 5; i++)
{
printf("x[%d].a = %d ", i, x[i].a);
printf("x[%d].b = %d ", i, x[i].b);
printf("x[%d].c = %d ", i, x[i].c);
printf("\n");
}
fun(x);
printf("----- After Call By Reference -----\n");
for (int i = 0; i < 5; i++)
{
printf("x[%d].a = %d ", i, x[i].a);
printf("x[%d].b = %d ", i, x[i].b);
printf("x[%d].c = %d ", i, x[i].c);
printf("\n");
}
return 0;
}
Output is as below
----- Before Call By Reference -----
x[0].a = 1 x[0].b = 2 x[0].c = 3
x[1].a = 4 x[1].b = 5 x[1].c = 6
x[2].a = 7 x[2].b = 8 x[2].c = 9
x[3].a = 10 x[3].b = 11 x[3].c = 12
x[4].a = 13 x[4].b = 14 x[4].c = 15
----- After Call By Reference -----
x[0].a = 777 x[0].b = 888 x[0].c = 999
x[1].a = 777 x[1].b = 888 x[1].c = 999
x[2].a = 777 x[2].b = 888 x[2].c = 999
x[3].a = 777 x[3].b = 888 x[3].c = 999
x[4].a = 777 x[4].b = 888 x[4].c = 999
Step 1 : Consider a structure array
struct ABC {
int a;
int b;
int c;
};
struct ABC x[5] = {
{.a = 1, .b = 2, .c = 3},
{.a = 4, .b = 5, .c = 6},
{.a = 7, .b = 8, .c = 9},
{.a = 10, .b = 11, .c = 12},
{.a = 13, .b = 14, .c = 15},
};
Step 2 : Pass full array by reference
fun( a + 2 );
Note that we are passing part of the array by reference
In this case, we are passing address of 3rd structure
Hence function fun
has read and write access to structures at indexes 2,3,4 in forward direction
Hence function fun
has read and write access to structures at indexes 0, 1 in backward direction
Step 3 : Define a function
void fun(struct ABC *ptr)
{
ptr[-2].a = 55; // Same as x[0]
ptr[-1].a = 66; // Same as x[1]
ptr[0].a = 77; // Same as x[2]
ptr[1].a = 88; // Same as x[3]
ptr[2].a = 99; // Same as x[4]
}
Note the relative access mechanism used inside function fun
See full program below
#include <stdio.h>
struct ABC {
int a;
int b;
int c;
};
void fun(struct ABC *ptr)
{
ptr[-2].a = 55; // Same as x[0]
ptr[-1].a = 66; // Same as x[1]
ptr[0].a = 77; // Same as x[2]
ptr[1].a = 88; // Same as x[3]
ptr[2].a = 99; // Same as x[4]
}
int main(void)
{
struct ABC x[5] = {
{.a = 1, .b = 2, .c = 3},
{.a = 4, .b = 5, .c = 6},
{.a = 7, .b = 8, .c = 9},
{.a = 10, .b = 11, .c = 12},
{.a = 13, .b = 14, .c = 15},
};
printf("----- Before Call By Reference -----\n");
for (int i = 0; i < 5; i++)
{
printf("x[%d].a = %d ", i, x[i].a);
printf("x[%d].b = %d ", i, x[i].b);
printf("x[%d].c = %d ", i, x[i].c);
printf("\n");
}
fun(x + 2);
printf("----- After Call By Reference -----\n");
for (int i = 0; i < 5; i++)
{
printf("x[%d].a = %d ", i, x[i].a);
printf("x[%d].b = %d ", i, x[i].b);
printf("x[%d].c = %d ", i, x[i].c);
printf("\n");
}
return 0;
}
Output is as below
----- Before Call By Reference -----
x[0].a = 1 x[0].b = 2 x[0].c = 3
x[1].a = 4 x[1].b = 5 x[1].c = 6
x[2].a = 7 x[2].b = 8 x[2].c = 9
x[3].a = 10 x[3].b = 11 x[3].c = 12
x[4].a = 13 x[4].b = 14 x[4].c = 15
----- After Call By Reference -----
x[0].a = 55 x[0].b = 2 x[0].c = 3
x[1].a = 66 x[1].b = 5 x[1].c = 6
x[2].a = 77 x[2].b = 8 x[2].c = 9
x[3].a = 88 x[3].b = 11 x[3].c = 12
x[4].a = 99 x[4].b = 14 x[4].c = 15
Step 1 : Consider a structure array
struct ABC {
int a;
int b;
int c;
};
struct ABC x[5] = {
{.a = 1, .b = 2, .c = 3},
{.a = 4, .b = 5, .c = 6},
{.a = 7, .b = 8, .c = 9},
{.a = 10, .b = 11, .c = 12},
{.a = 13, .b = 14, .c = 15},
};
Step 2 : Pass the address of array
a
to functionfun
fun(&a);
Step 3 : Define the function
fun
void fun( struct ABC (*ptr)[5] )
{
}
Note that struct ABC (*ptr)[5]
is pointer to an array of 5 structures
Which means incrementing ptr
will increment by 5 Structures and decrementing ptr
will decrement by 5 Structures
Step 4 : Access individual structures inside function
fun
void fun( struct ABC (*ptr)[10] )
{
//Change individual structures
(*ptr)[0].a = 55;
(*ptr)[1].a = 66;
(*ptr)[2].a = 77;
(*ptr)[3].a = 88;
(*ptr)[4].a = 99;
}
See the full program below
#include <stdio.h>
struct ABC {
int a;
int b;
int c;
};
void fun( struct ABC (*ptr)[5] )
{
//Change individual structures
(*ptr)[0].a = 55;
(*ptr)[1].a = 66;
(*ptr)[2].a = 77;
(*ptr)[3].a = 88;
(*ptr)[4].a = 99;
}
int main(void)
{
struct ABC x[5] = {
{.a = 1, .b = 2, .c = 3},
{.a = 4, .b = 5, .c = 6},
{.a = 7, .b = 8, .c = 9},
{.a = 10, .b = 11, .c = 12},
{.a = 13, .b = 14, .c = 15},
};
printf("----- Before Call By Reference -----\n");
for (int i = 0; i < 5; i++)
{
printf("x[%d].a = %d ", i, x[i].a);
printf("x[%d].b = %d ", i, x[i].b);
printf("x[%d].c = %d ", i, x[i].c);
printf("\n");
}
fun(&x);
printf("----- After Call By Reference -----\n");
for (int i = 0; i < 5; i++)
{
printf("x[%d].a = %d ", i, x[i].a);
printf("x[%d].b = %d ", i, x[i].b);
printf("x[%d].c = %d ", i, x[i].c);
printf("\n");
}
return 0;
}
Output is as below
----- Before Call By Reference -----
x[0].a = 1 x[0].b = 2 x[0].c = 3
x[1].a = 4 x[1].b = 5 x[1].c = 6
x[2].a = 7 x[2].b = 8 x[2].c = 9
x[3].a = 10 x[3].b = 11 x[3].c = 12
x[4].a = 13 x[4].b = 14 x[4].c = 15
----- After Call By Reference -----
x[0].a = 55 x[0].b = 2 x[0].c = 3
x[1].a = 66 x[1].b = 5 x[1].c = 6
x[2].a = 77 x[2].b = 8 x[2].c = 9
x[3].a = 88 x[3].b = 11 x[3].c = 12
x[4].a = 99 x[4].b = 14 x[4].c = 15
Other topics of structure and functions
Current Module
Previous Module
Next Module
Other Modules