Functions and Structure Triple Pointer
In this section, you are going to learn
What are the calling conventions of structure triple pointer ?
Call by Value
Call by Reference
Revisit Basics : Basics of Structure Triple Pointers
Topics in this section,
struct ABC ***tp;
Consider a structure triple pointer
struct ABC {
int a;
int b;
int c;
};
struct ABC ***tp;
Let us answer few basic questions about structure triple pointer
If fun(x)
is the function call, then fun(typeof(x))
is the prototype / definition
Function Call |
Function Definition |
Observations |
---|---|---|
fun(tp[0][0][0]) |
void fun(struct ABC x) {} |
|
fun(tp[1][0][0]) |
void fun(struct ABC x) {} |
|
fun(&tp[0][0][0]) |
void fun(struct ABC *p) {} |
|
fun(&tp[1][0][0]) |
void fun(struct ABC *p) {} |
|
fun(tp[0][0]) |
void fun(struct ABC *p) {} |
|
fun(tp[1][0]) |
void fun(struct ABC *p) {} |
|
fun(&tp[0][0]) |
void fun(struct ABC **p) {} |
|
fun(&tp[1][0]) |
void fun(struct ABC **p) {} |
|
fun(**tp) |
void fun(struct ABC *p) {} |
|
fun(*(*(tp + 1) + 0)) |
void fun(struct ABC *p) {} |
|
fun(tp[0]) |
void fun(struct ABC **p) {} |
|
fun(tp[1]) |
void fun(struct ABC **p) {} |
|
fun(&tp[0]) |
void fun(struct ABC ***p) {} |
|
fun(*tp) |
void fun(struct ABC **p) {} |
|
fun(*(tp + 1)) |
void fun(struct ABC **p) {} |
|
fun(tp) |
void fun(struct ABC ***p) {} |
|
fun(&tp) |
void fun(struct ABC ****p) {} |
|
Let us understand the reason behind above prototypes !
If Declaration has THREE dereference operators, and
Expression has THREE dereference operators * * *, and
Expression does not have
&
then it is call by value
If Declaration has THREE dereference operators, and
Expression has THREE dereference operators * * [ ], and
Expression does not have
&
then it is call by value
If Declaration has THREE dereference operators, and
Expression has THREE dereference operators * [ ] [ ], and
Expression does not have
&
then it is call by value
If Declaration has THREE dereference operators, and
Expression has THREE dereference operators [] [] [], and
Expression does not have
&
then it is call by value
Let us look at examples
Step 1 : Consider a triple dimension array created using a structure triple pointer
struct ABC {
int a;
int b;
int c;
};
struct ABC ***tp;
tp = malloc( 2 * sizeof(struct ABC **) );
for (int i = 0; i < 2; i++)
{
tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
for (int j = 0; j < 3; j++)
{
tp[i][j] = malloc( 4 * sizeof(struct ABC) );
}
}
Condition 1 : Declaration has THREE dereference operators [ ], [ ] and [ ]
Step 2 : Consider an expression
tp[1][1][1]
Condition 2 : Expression has THREE dereference operators [ ], [ ] and [ ]
Note : [ ]
and *
are dereference operators
Condition 3 : Expression DOES NOT have &
operator
Hence tp[1][1][1]
is Call By Value
Step 1 : Consider a triple dimension array created using a structure triple pointer
struct ABC {
int a;
int b;
int c;
};
struct ABC ***tp;
tp = malloc( 2 * sizeof(struct ABC **) );
for (int i = 0; i < 2; i++)
{
tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
for (int j = 0; j < 3; j++)
{
tp[i][j] = malloc( 4 * sizeof(struct ABC) );
}
}
Condition 1 : Declaration has THREE dereference operators [ ], [ ] and [ ]
Step 2 : Consider an expression
***tp
Condition 2 : Expression has THREE dereference operators *, * and *
Note : [ ]
and *
are dereference operators
Condition 3 : Expression DOES NOT have &
operator
Hence ***tp
is Call By Value
If Declaration has THREE dereference operators, and
Expression has THREE dereference operators * * * OR * * [] OR * [] [] OR [] [] [] and
Expression has &
then it is call by reference
Example : &tp[0][0][0], &tp[1][2][3]
If Declaration has THREE dereference operators, and
Expression has TWO dereference operator * * OR [] [] OR * []
then it is call by reference
Example : tp[0][0]
If Declaration has THREE dereference operators, and
Expression has ONE dereference operators, * OR [ ]
then it is call by reference
Example : tp[0]
If Declaration has THREE dereference operators, and
Expression has ZERO dereference operators
then it is call by reference
Example : tp
Step 1 : Consider a triple dimension array created using a structure triple pointer
struct ABC {
int a;
int b;
int c;
};
struct ABC ***tp;
tp = malloc( 2 * sizeof(struct ABC **) );
for (int i = 0; i < 2; i++)
{
tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
for (int j = 0; j < 3; j++)
{
tp[i][j] = malloc( 4 * sizeof(struct ABC) );
}
}
Condition 1 : Declaration has THREE dereference operators [ ] [ ] and [ ]
Step 2 : Consider an expression
&tp[1][1][1]
Condition 2 : Expression has THREE dereference operators [ ] [ ] and [ ]
Note : [ ]
and *
are dereference operators
Condition 3 : Expression has &
operator
Hence &tp[1][1][1]
is Call By Reference
Step 1 : Consider a triple dimension array created using a structure triple pointer
struct ABC {
int a;
int b;
int c;
};
struct ABC ***tp;
tp = malloc( 2 * sizeof(struct ABC **) );
for (int i = 0; i < 2; i++)
{
tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
for (int j = 0; j < 3; j++)
{
tp[i][j] = malloc( 4 * sizeof(struct ABC) );
}
}
Condition 1 : Declaration has THREE dereference operators [ ] [ ] and [ ]
Step 2 : Consider an expression
tp[1]
Condition 2 : Expression has ONE dereference operator
Note : [ ]
and *
are dereference operators
Condition 3 : Expression DOES NOT have &
operator
Hence tp[1]
is Call By Reference
Let us look at examples of Call by Value
Step 1 : Consider a triple dimension array created using a structure triple pointer
struct ABC {
int a;
int b;
int c;
};
struct ABC ***tp;
tp = malloc( 2 * sizeof(struct ABC **) );
for (int i = 0; i < 2; i++)
{
tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
for (int j = 0; j < 3; j++)
{
tp[i][j] = malloc( 4 * sizeof(struct ABC) );
}
}
Step 2 : Pass tp[0][0][0], tp[1][0][0] to a function
fun
fun(tp[0][0][0]);
fun(tp[1][0][0]);
Step 3 : Define function
fun
void fun(struct ABC y)
{
y.a = 55;
y.b = 66;
y.c = 77;
}
Step 4 : Note that it is call by Value for below reason
Condition 1 : Declaration has THREE dereference operators [ ] [ ] and [ ]
Condition 2 : Expression has THREE dereference operators [ ] [ ] and [ ]
Condition 3 : Expression DOES NOT have &
operator
Means changing value of structure inside function DOES NOT affect value of structure in Caller !
Step 5 : Free memory after use
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
free( tp[i][j] );
}
free( tp[i] );
}
free(tp);
See full program below
#include <stdio.h>
#include <stdlib.h>
struct ABC {
int a;
int b;
int c;
};
void fun(struct ABC y)
{
y.a = 55;
y.b = 66;
y.c = 77;
}
int main(void)
{
struct ABC ***tp;
tp = malloc( 2 * sizeof(struct ABC **) );
for (int i = 0; i < 2; i++)
{
tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
for (int j = 0; j < 3; j++)
{
tp[i][j] = malloc( 4 * sizeof(struct ABC) );
}
}
int data = 1;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
for (int k = 0; k < 4; k++)
{
tp[i][j][k].a = data++;
tp[i][j][k].b = data++;
tp[i][j][k].c = data++;
}
}
}
printf("----- Before Call By Value -----\n");
printf("tp[0][0][0].a = %d\n", tp[0][0][0].a );
printf("tp[0][0][0].b = %d\n", tp[0][0][0].b );
printf("tp[0][0][0].c = %d\n", tp[0][0][0].c );
printf("tp[1][0][0].a = %d\n", tp[1][0][0].a );
printf("tp[1][0][0].b = %d\n", tp[1][0][0].b );
printf("tp[1][0][0].c = %d\n", tp[1][0][0].c );
fun(tp[0][0][0]);
fun(tp[1][0][0]);
printf("----- After Call By Value -----\n");
printf("tp[0][0][0].a = %d\n", tp[0][0][0].a );
printf("tp[0][0][0].b = %d\n", tp[0][0][0].b );
printf("tp[0][0][0].c = %d\n", tp[0][0][0].c );
printf("tp[1][0][0].a = %d\n", tp[1][0][0].a );
printf("tp[1][0][0].b = %d\n", tp[1][0][0].b );
printf("tp[1][0][0].c = %d\n", tp[1][0][0].c );
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
free( tp[i][j] );
}
free( tp[i] );
}
free(tp);
return 0;
}
Output is as below
----- Before Call By Value -----
tp[0][0][0].a = 1
tp[0][0][0].b = 2
tp[0][0][0].c = 3
tp[1][0][0].a = 37
tp[1][0][0].b = 38
tp[1][0][0].c = 39
----- After Call By Value -----
tp[0][0][0].a = 1
tp[0][0][0].b = 2
tp[0][0][0].c = 3
tp[1][0][0].a = 37
tp[1][0][0].b = 38
tp[1][0][0].c = 39
Step 1 : Consider a triple dimension array created using a structure triple pointer
struct ABC {
int a;
int b;
int c;
};
struct ABC ***tp;
tp = malloc( 2 * sizeof(struct ABC **) );
for (int i = 0; i < 2; i++)
{
tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
for (int j = 0; j < 3; j++)
{
tp[i][j] = malloc( 4 * sizeof(struct ABC) );
}
}
Step 2 : Pass ***tp, *(*(*(tp + 1) + 0) + 0) to a function
fun
fun( ***tp );
fun( *(*(*(tp + 1) + 0) + 0) );
Step 3 : Define function
fun
void fun(struct ABC y)
{
y.a = 55;
y.b = 66;
y.c = 77;
}
Step 4 : Note that it is call by Value for below reason
Condition 1 : Declaration has THREE dereference operators [ ] [ ] and [ ]
Condition 2 : Expression has THREE dereference operators * * and *
Condition 3 : Expression DOES NOT have &
operator
Means changing value of structure inside function DOES NOT affect value of structure in Caller !
Step 5 : Free memory after use
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
free( tp[i][j] );
}
free( tp[i] );
}
free(tp);
See full program below
#include <stdio.h>
#include <stdlib.h>
struct ABC {
int a;
int b;
int c;
};
void fun(struct ABC y)
{
y.a = 55;
y.b = 66;
y.c = 77;
}
int main(void)
{
struct ABC ***tp;
tp = malloc( 2 * sizeof(struct ABC **) );
for (int i = 0; i < 2; i++)
{
tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
for (int j = 0; j < 3; j++)
{
tp[i][j] = malloc( 4 * sizeof(struct ABC) );
}
}
int data = 1;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
for (int k = 0; k < 4; k++)
{
tp[i][j][k].a = data++;
tp[i][j][k].b = data++;
tp[i][j][k].c = data++;
}
}
}
printf("----- Before Call By Value -----\n");
printf(" (***tp).a = %d\n", (***tp).a );
printf(" (***tp).b = %d\n", (***tp).b );
printf(" (***tp).c = %d\n", (***tp).c );
printf(" (*(*(*(tp + 1) + 0) + 0)).a = %d\n", (*(*(*(tp + 1) + 0) + 0)).a );
printf(" (*(*(*(tp + 1) + 0) + 0)).b = %d\n", (*(*(*(tp + 1) + 0) + 0)).b );
printf(" (*(*(*(tp + 1) + 0) + 0)).c = %d\n", (*(*(*(tp + 1) + 0) + 0)).c );
fun( ***tp );
fun( *(*(*(tp + 1) + 0) + 0) );
printf("----- After Call By Value -----\n");
printf(" (***tp).a = %d\n", (***tp).a );
printf(" (***tp).b = %d\n", (***tp).b );
printf(" (***tp).c = %d\n", (***tp).c );
printf(" (*(*(*(tp + 1) + 0) + 0)).a = %d\n", (*(*(*(tp + 1) + 0) + 0)).a );
printf(" (*(*(*(tp + 1) + 0) + 0)).b = %d\n", (*(*(*(tp + 1) + 0) + 0)).b );
printf(" (*(*(*(tp + 1) + 0) + 0)).c = %d\n", (*(*(*(tp + 1) + 0) + 0)).c );
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
free( tp[i][j] );
}
free( tp[i] );
}
free(tp);
return 0;
}
Output is as below
----- Before Call By Value -----
(***tp).a = 1
(***tp).b = 2
(***tp).c = 3
(*(*(*(tp + 1) + 0) + 0)).a = 37
(*(*(*(tp + 1) + 0) + 0)).b = 38
(*(*(*(tp + 1) + 0) + 0)).c = 39
----- After Call By Value -----
(***tp).a = 1
(***tp).b = 2
(***tp).c = 3
(*(*(*(tp + 1) + 0) + 0)).a = 37
(*(*(*(tp + 1) + 0) + 0)).b = 38
(*(*(*(tp + 1) + 0) + 0)).c = 39
Let us look at examples of Call by Reference
Step 1 : Consider a triple dimension array created using a structure triple pointer
struct ABC {
int a;
int b;
int c;
};
struct ABC ***tp;
tp = malloc( 2 * sizeof(struct ABC **) );
for (int i = 0; i < 2; i++)
{
tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
for (int j = 0; j < 3; j++)
{
tp[i][j] = malloc( 4 * sizeof(struct ABC) );
}
}
There are 6 single dimension arrays in struct ABC \*\*\*tp
with respect to above allocation
tp[0][0]
tp[0][1]
tp[0][2]
tp[1][0]
tp[1][1]
tp[1][2]
Step 2.1 : Method 1 : Pass tp[0][0], tp[1][0] to a function
fun
fun( tp[0][0] );
fun( tp[1][0] );
Step 2.2 : Method 2 : Pass &tp[0][0][0], &tp[1][0][0] to a function
fun
fun( &tp[0][0][0] );
fun( &tp[1][0][0] );
Step 2.3 : Method 3 : Pass **tp, *(*(tp + 1) + 0) to a function
fun
fun( **tp );
fun( *(*(tp + 1) + 0) );
Step 3.1 : Define function
fun
void fun(struct ABC *ptr)
{
}
Step 3.2 : Note that it is call by Reference. Means contents of single dimension array can be changed inside function
fun
void fun(struct ABC *ptr)
{
// 1. Caller has passed single pointer pointing to array of 4 structure objects
// 2. Hence, in this function 4 structure objects can be accessed and changed
int data = 666;
for (int i = 0; i < 4; i++)
{
ptr[i].a = data++;
ptr[i].b = data++;
ptr[i].c = data++;
}
}
Step 4 : Free memory after use
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
free( tp[i][j] );
}
free( tp[i] );
}
free(tp);
See full program below
#include <stdio.h>
#include <stdlib.h>
struct ABC {
int a;
int b;
int c;
};
void fun(struct ABC *ptr)
{
// 1. Caller has passed single pointer pointing to array of 4 structure objects
// 2. Hence, in this function 4 structure objects can be accessed and changed
int data = 666;
for (int i = 0; i < 4; i++)
{
ptr[i].a = data++;
ptr[i].b = data++;
ptr[i].c = data++;
}
}
int main(void)
{
struct ABC ***tp;
tp = malloc( 2 * sizeof(struct ABC **) );
for (int i = 0; i < 2; i++)
{
tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
for (int j = 0; j < 3; j++)
{
tp[i][j] = malloc( 4 * sizeof(struct ABC) );
}
}
int data = 1;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
for (int k = 0; k < 4; k++)
{
tp[i][j][k].a = data++;
tp[i][j][k].b = data++;
tp[i][j][k].c = data++;
}
}
}
printf("----- Before Call By Reference -----\n");
for (int i = 0; i < 4; i++)
{
printf("tp[0][0][%d].a = %d\n", i, tp[0][0][i].a);
printf("tp[0][0][%d].b = %d\n", i, tp[0][0][i].b);
printf("tp[0][0][%d].c = %d\n", i, tp[0][0][i].c);
}
for (int i = 0; i < 4; i++)
{
printf("tp[1][0][%d].a = %d\n", i, tp[1][0][i].a);
printf("tp[1][0][%d].b = %d\n", i, tp[1][0][i].b);
printf("tp[1][0][%d].c = %d\n", i, tp[1][0][i].c);
}
// Method 1 : Access Single dimension arrays
fun( tp[0][0] );
fun( tp[1][0] );
// Method 2 : Access Single dimension arrays
fun( &tp[0][0][0] );
fun( &tp[1][0][0] );
// Method 3 : Access Single dimension arrays
fun( **tp );
fun( *(*(tp + 1) + 0) );
printf("----- After Call By Reference -----\n");
for (int i = 0; i < 4; i++)
{
printf("tp[0][0][%d].a = %d\n", i, tp[0][0][i].a);
printf("tp[0][0][%d].b = %d\n", i, tp[0][0][i].b);
printf("tp[0][0][%d].c = %d\n", i, tp[0][0][i].c);
}
for (int i = 0; i < 4; i++)
{
printf("tp[1][0][%d].a = %d\n", i, tp[1][0][i].a);
printf("tp[1][0][%d].b = %d\n", i, tp[1][0][i].b);
printf("tp[1][0][%d].c = %d\n", i, tp[1][0][i].c);
}
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
free( tp[i][j] );
}
free( tp[i] );
}
free(tp);
return 0;
}
Output is as below
----- Before Call By Reference -----
tp[0][0][0].a = 1
tp[0][0][0].b = 2
tp[0][0][0].c = 3
tp[0][0][1].a = 4
tp[0][0][1].b = 5
tp[0][0][1].c = 6
tp[0][0][2].a = 7
tp[0][0][2].b = 8
tp[0][0][2].c = 9
tp[0][0][3].a = 10
tp[0][0][3].b = 11
tp[0][0][3].c = 12
tp[1][0][0].a = 37
tp[1][0][0].b = 38
tp[1][0][0].c = 39
tp[1][0][1].a = 40
tp[1][0][1].b = 41
tp[1][0][1].c = 42
tp[1][0][2].a = 43
tp[1][0][2].b = 44
tp[1][0][2].c = 45
tp[1][0][3].a = 46
tp[1][0][3].b = 47
tp[1][0][3].c = 48
----- After Call By Reference -----
tp[0][0][0].a = 666
tp[0][0][0].b = 667
tp[0][0][0].c = 668
tp[0][0][1].a = 669
tp[0][0][1].b = 670
tp[0][0][1].c = 671
tp[0][0][2].a = 672
tp[0][0][2].b = 673
tp[0][0][2].c = 674
tp[0][0][3].a = 675
tp[0][0][3].b = 676
tp[0][0][3].c = 677
tp[1][0][0].a = 666
tp[1][0][0].b = 667
tp[1][0][0].c = 668
tp[1][0][1].a = 669
tp[1][0][1].b = 670
tp[1][0][1].c = 671
tp[1][0][2].a = 672
tp[1][0][2].b = 673
tp[1][0][2].c = 674
tp[1][0][3].a = 675
tp[1][0][3].b = 676
tp[1][0][3].c = 677
Step 1 : Consider a triple dimension array created using a structure triple pointer
struct ABC {
int a;
int b;
int c;
};
struct ABC ***tp;
tp = malloc( 2 * sizeof(struct ABC **) );
for (int i = 0; i < 2; i++)
{
tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
for (int j = 0; j < 3; j++)
{
tp[i][j] = malloc( 4 * sizeof(struct ABC) );
}
}
There are 6 single dimension arrays in above location
tp[0][0]
tp[0][1]
tp[0][2]
tp[1][0]
tp[1][1]
tp[1][2]
Address of single dimension arrays is simply
&tp[0][0]
&tp[0][1]
&tp[0][2]
&tp[1][0]
&tp[1][1]
&tp[1][2]
Step 2.1 : Method 1 : Pass address of single dimension arrays to a function
fun
fun( &tp[0][0] );
fun( &tp[1][0] );
Step 2.2 : Method 2 : Pass address of single dimension arrays to a function
fun
fun( tp[0] );
fun( tp[1] );
Step 2.3 : Method 2 : Pass address of single dimension arrays to a function
fun
fun( *tp );
fun( *(tp + 1) );
Step 3.1 : Define the function
fun
void fun(struct ABC **ptr )
{
}
Step 3.2 : Define the function
fun
to change the contents of single dimension array structure by structure
void fun(struct ABC **ptr)
{
int data = 666;
for (int i = 0; i < 4; i++)
{
(*ptr)[i].a = data++;
(*ptr)[i].b = data++;
(*ptr)[i].c = data++;
}
}
Step 4 : Free memory after use
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
free( tp[i][j] );
}
free( tp[i] );
}
free(tp);
See full program below
#include <stdio.h>
#include <stdlib.h>
struct ABC {
int a;
int b;
int c;
};
void fun(struct ABC **ptr)
{
int data = 666;
for (int i = 0; i < 4; i++)
{
(*ptr)[i].a = data++;
(*ptr)[i].b = data++;
(*ptr)[i].c = data++;
}
}
int main(void)
{
struct ABC ***tp;
tp = malloc( 2 * sizeof(struct ABC **) );
for (int i = 0; i < 2; i++)
{
tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
for (int j = 0; j < 3; j++)
{
tp[i][j] = malloc( 4 * sizeof(struct ABC) );
}
}
int data = 1;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
for (int k = 0; k < 4; k++)
{
tp[i][j][k].a = data++;
tp[i][j][k].b = data++;
tp[i][j][k].c = data++;
}
}
}
printf("----- Before Call By Reference -----\n");
for (int i = 0; i < 4; i++)
{
printf("tp[0][0][i].a = %d ", tp[0][0][i].a);
printf("tp[0][0][i].b = %d ", tp[0][0][i].b);
printf("tp[0][0][i].c = %d ", tp[0][0][i].c);
printf("\n");
}
for (int i = 0; i < 4; i++)
{
printf("tp[1][0][i].a = %d ", tp[1][0][i].a);
printf("tp[1][0][i].b = %d ", tp[1][0][i].b);
printf("tp[1][0][i].c = %d ", tp[1][0][i].c);
printf("\n");
}
// Method 1 : Access Single dimension arrays
fun( &tp[0][0] );
fun( &tp[1][0] );
// Method 2 : Access Single dimension arrays
fun( tp[0] );
fun( tp[1] );
// Method 3 : Access Single dimension arrays
fun( *tp );
fun( *(tp + 1) );
printf("----- After Call By Reference -----\n");
for (int i = 0; i < 4; i++)
{
printf("tp[0][0][i].a = %d ", tp[0][0][i].a);
printf("tp[0][0][i].b = %d ", tp[0][0][i].b);
printf("tp[0][0][i].c = %d ", tp[0][0][i].c);
printf("\n");
}
for (int i = 0; i < 4; i++)
{
printf("tp[1][0][i].a = %d ", tp[1][0][i].a);
printf("tp[1][0][i].b = %d ", tp[1][0][i].b);
printf("tp[1][0][i].c = %d ", tp[1][0][i].c);
printf("\n");
}
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
free( tp[i][j] );
}
free( tp[i] );
}
free(tp);
return 0;
}
Output is as below
----- Before Call By Reference -----
tp[0][0][i].a = 1 tp[0][0][i].b = 2 tp[0][0][i].c = 3
tp[0][0][i].a = 4 tp[0][0][i].b = 5 tp[0][0][i].c = 6
tp[0][0][i].a = 7 tp[0][0][i].b = 8 tp[0][0][i].c = 9
tp[0][0][i].a = 10 tp[0][0][i].b = 11 tp[0][0][i].c = 12
tp[1][0][i].a = 37 tp[1][0][i].b = 38 tp[1][0][i].c = 39
tp[1][0][i].a = 40 tp[1][0][i].b = 41 tp[1][0][i].c = 42
tp[1][0][i].a = 43 tp[1][0][i].b = 44 tp[1][0][i].c = 45
tp[1][0][i].a = 46 tp[1][0][i].b = 47 tp[1][0][i].c = 48
----- After Call By Reference -----
tp[0][0][i].a = 666 tp[0][0][i].b = 667 tp[0][0][i].c = 668
tp[0][0][i].a = 669 tp[0][0][i].b = 670 tp[0][0][i].c = 671
tp[0][0][i].a = 672 tp[0][0][i].b = 673 tp[0][0][i].c = 674
tp[0][0][i].a = 675 tp[0][0][i].b = 676 tp[0][0][i].c = 677
tp[1][0][i].a = 666 tp[1][0][i].b = 667 tp[1][0][i].c = 668
tp[1][0][i].a = 669 tp[1][0][i].b = 670 tp[1][0][i].c = 671
tp[1][0][i].a = 672 tp[1][0][i].b = 673 tp[1][0][i].c = 674
tp[1][0][i].a = 675 tp[1][0][i].b = 676 tp[1][0][i].c = 677
Step 1 : Consider a triple dimension array created using a structure triple pointer
struct ABC ***tp;
tp = malloc( 2 * sizeof(struct ABC **) );
for (int i = 0; i < 2; i++)
{
tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
for (int j = 0; j < 3; j++)
{
tp[i][j] = malloc( 4 * sizeof(struct ABC) );
}
}
Step 2 : Pass Double dimension array to function
fun
fun(tp[1]);
Step 3.1 : Define function
fun
void fun(struct ABC **ptr)
{
}
Step 3.2 : Access and Change structures inside function
fun
void fun(struct ABC **ptr)
{
int data = 666;
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 4; j++)
{
ptr[i][j].a = data++;
ptr[i][j].a = data++;
ptr[i][j].a = data++;
}
}
}
Step 4 : Free memory after use
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
free( tp[i][j] );
}
free( tp[i] );
}
free(tp);
Step 5 : See the full program below
#include <stdio.h>
#include <stdlib.h>
struct ABC {
int a;
int b;
int c;
};
void fun(struct ABC **ptr)
{
int data = 666;
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 4; j++)
{
ptr[i][j].a = data++;
ptr[i][j].b = data++;
ptr[i][j].c = data++;
}
}
}
int main(void)
{
struct ABC ***tp;
tp = malloc( 2 * sizeof(struct ABC **) );
for (int i = 0; i < 2; i++)
{
tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
for (int j = 0; j < 3; j++)
{
tp[i][j] = malloc( 4 * sizeof(struct ABC) );
}
}
int data = 1;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
for (int k = 0; k < 4; k++)
{
tp[i][j][k].a = data++;
tp[i][j][k].b = data++;
tp[i][j][k].c = data++;
}
}
}
printf("----- Before Call By Reference -----\n");
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 4; j++)
{
printf("tp[1][%d][%d].a = %d ", i, j, tp[1][i][j].a );
printf("tp[1][%d][%d].b = %d ", i, j, tp[1][i][j].b );
printf("tp[1][%d][%d].c = %d ", i, j, tp[1][i][j].c );
printf("\n");
}
printf("\n");
}
fun(tp[1]);
printf("----- After Call By Reference -----\n");
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 4; j++)
{
printf("tp[1][%d][%d].a = %d ", i, j, tp[1][i][j].a );
printf("tp[1][%d][%d].b = %d ", i, j, tp[1][i][j].b );
printf("tp[1][%d][%d].c = %d ", i, j, tp[1][i][j].c );
printf("\n");
}
printf("\n");
}
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
free( tp[i][j] );
}
free( tp[i] );
}
return 0;
}
Step 5 : Output is as below
----- Before Call By Reference -----
tp[1][0][0].a = 37 tp[1][0][0].b = 38 tp[1][0][0].c = 39
tp[1][0][1].a = 40 tp[1][0][1].b = 41 tp[1][0][1].c = 42
tp[1][0][2].a = 43 tp[1][0][2].b = 44 tp[1][0][2].c = 45
tp[1][0][3].a = 46 tp[1][0][3].b = 47 tp[1][0][3].c = 48
tp[1][1][0].a = 49 tp[1][1][0].b = 50 tp[1][1][0].c = 51
tp[1][1][1].a = 52 tp[1][1][1].b = 53 tp[1][1][1].c = 54
tp[1][1][2].a = 55 tp[1][1][2].b = 56 tp[1][1][2].c = 57
tp[1][1][3].a = 58 tp[1][1][3].b = 59 tp[1][1][3].c = 60
tp[1][2][0].a = 61 tp[1][2][0].b = 62 tp[1][2][0].c = 63
tp[1][2][1].a = 64 tp[1][2][1].b = 65 tp[1][2][1].c = 66
tp[1][2][2].a = 67 tp[1][2][2].b = 68 tp[1][2][2].c = 69
tp[1][2][3].a = 70 tp[1][2][3].b = 71 tp[1][2][3].c = 72
----- After Call By Reference -----
tp[1][0][0].a = 666 tp[1][0][0].b = 667 tp[1][0][0].c = 668
tp[1][0][1].a = 669 tp[1][0][1].b = 670 tp[1][0][1].c = 671
tp[1][0][2].a = 672 tp[1][0][2].b = 673 tp[1][0][2].c = 674
tp[1][0][3].a = 675 tp[1][0][3].b = 676 tp[1][0][3].c = 677
tp[1][1][0].a = 678 tp[1][1][0].b = 679 tp[1][1][0].c = 680
tp[1][1][1].a = 681 tp[1][1][1].b = 682 tp[1][1][1].c = 683
tp[1][1][2].a = 684 tp[1][1][2].b = 685 tp[1][1][2].c = 686
tp[1][1][3].a = 687 tp[1][1][3].b = 688 tp[1][1][3].c = 689
tp[1][2][0].a = 690 tp[1][2][0].b = 691 tp[1][2][0].c = 692
tp[1][2][1].a = 693 tp[1][2][1].b = 694 tp[1][2][1].c = 695
tp[1][2][2].a = 696 tp[1][2][2].b = 697 tp[1][2][2].c = 698
tp[1][2][3].a = 699 tp[1][2][3].b = 700 tp[1][2][3].c = 701
Step 1 : Consider a triple dimension array created using a structure triple pointer
struct ABC {
int a;
int b;
int c;
};
struct ABC ***tp;
tp = malloc( 2 * sizeof(struct ABC **) );
for (int i = 0; i < 2; i++)
{
tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
for (int j = 0; j < 3; j++)
{
tp[i][j] = malloc( 4 * sizeof(struct ABC) );
}
}
Step 2 : Pass Address of Double dimension array to function
fun
fun(&tp[1]);
Step 3.1 : Define function
fun
void fun(struct ABC ***ptr)
{
}
Step 3.2 : Access and Change structures inside function
fun
void fun(struct ABC ***ptr)
{
int data = 666;
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 4; j++)
{
(*ptr)[i][j].a = data++;
(*ptr)[i][j].b = data++;
(*ptr)[i][j].c = data++;
}
}
}
Step 4 : Free memory after use
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
free( tp[i][j] );
}
free( tp[i] );
}
free(tp);
Step 5 : See the full program below
#include <stdio.h>
#include <stdlib.h>
struct ABC {
int a;
int b;
int c;
};
void fun(struct ABC ***ptr)
{
int data = 666;
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 4; j++)
{
(*ptr)[i][j].a = data++;
(*ptr)[i][j].b = data++;
(*ptr)[i][j].c = data++;
}
}
}
int main(void)
{
struct ABC ***tp;
tp = malloc( 2 * sizeof(struct ABC **) );
for (int i = 0; i < 2; i++)
{
tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
for (int j = 0; j < 3; j++)
{
tp[i][j] = malloc( 4 * sizeof(struct ABC) );
}
}
int data = 1;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
for (int k = 0; k < 4; k++)
{
tp[i][j][k].a = data++;
tp[i][j][k].b = data++;
tp[i][j][k].c = data++;
}
}
}
printf("----- Before Call By Reference -----\n");
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 4; j++)
{
printf("tp[1][%d][%d].a = %d ", i, j, tp[1][i][j].a );
printf("tp[1][%d][%d].b = %d ", i, j, tp[1][i][j].b );
printf("tp[1][%d][%d].c = %d ", i, j, tp[1][i][j].c );
printf("\n");
}
printf("\n");
}
fun(&tp[1]);
printf("----- After Call By Reference -----\n");
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 4; j++)
{
printf("tp[1][%d][%d].a = %d ", i, j, tp[1][i][j].a );
printf("tp[1][%d][%d].b = %d ", i, j, tp[1][i][j].b );
printf("tp[1][%d][%d].c = %d ", i, j, tp[1][i][j].c );
printf("\n");
}
printf("\n");
}
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
free( tp[i][j] );
}
free( tp[i] );
}
free(tp);
return 0;
}
Step 5 : Output is as below
----- Before Call By Reference -----
tp[1][0][0].a = 37 tp[1][0][0].b = 38 tp[1][0][0].c = 39
tp[1][0][1].a = 40 tp[1][0][1].b = 41 tp[1][0][1].c = 42
tp[1][0][2].a = 43 tp[1][0][2].b = 44 tp[1][0][2].c = 45
tp[1][0][3].a = 46 tp[1][0][3].b = 47 tp[1][0][3].c = 48
tp[1][1][0].a = 49 tp[1][1][0].b = 50 tp[1][1][0].c = 51
tp[1][1][1].a = 52 tp[1][1][1].b = 53 tp[1][1][1].c = 54
tp[1][1][2].a = 55 tp[1][1][2].b = 56 tp[1][1][2].c = 57
tp[1][1][3].a = 58 tp[1][1][3].b = 59 tp[1][1][3].c = 60
tp[1][2][0].a = 61 tp[1][2][0].b = 62 tp[1][2][0].c = 63
tp[1][2][1].a = 64 tp[1][2][1].b = 65 tp[1][2][1].c = 66
tp[1][2][2].a = 67 tp[1][2][2].b = 68 tp[1][2][2].c = 69
tp[1][2][3].a = 70 tp[1][2][3].b = 71 tp[1][2][3].c = 72
----- After Call By Reference -----
tp[1][0][0].a = 666 tp[1][0][0].b = 667 tp[1][0][0].c = 668
tp[1][0][1].a = 669 tp[1][0][1].b = 670 tp[1][0][1].c = 671
tp[1][0][2].a = 672 tp[1][0][2].b = 673 tp[1][0][2].c = 674
tp[1][0][3].a = 675 tp[1][0][3].b = 676 tp[1][0][3].c = 677
tp[1][1][0].a = 678 tp[1][1][0].b = 679 tp[1][1][0].c = 680
tp[1][1][1].a = 681 tp[1][1][1].b = 682 tp[1][1][1].c = 683
tp[1][1][2].a = 684 tp[1][1][2].b = 685 tp[1][1][2].c = 686
tp[1][1][3].a = 687 tp[1][1][3].b = 688 tp[1][1][3].c = 689
tp[1][2][0].a = 690 tp[1][2][0].b = 691 tp[1][2][0].c = 692
tp[1][2][1].a = 693 tp[1][2][1].b = 694 tp[1][2][1].c = 695
tp[1][2][2].a = 696 tp[1][2][2].b = 697 tp[1][2][2].c = 698
tp[1][2][3].a = 699 tp[1][2][3].b = 700 tp[1][2][3].c = 701
Step 1 : Consider a triple dimension array created using a structure triple pointer
struct ABC {
int a;
int b;
int c;
};
struct ABC ***tp;
tp = malloc( 2 * sizeof(struct ABC **) );
for (int i = 0; i < 2; i++)
{
tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
for (int j = 0; j < 3; j++)
{
tp[i][j] = malloc( 4 * sizeof(struct ABC) );
}
}
Step 2 : Pass Address of Triple Dimension array to a function
fun(&tp);
Step 3.1 : Define function
fun
void fun(struct ABC ****ptr )
{
}
Step 3.2 : Access and change individual structures inside function
fun
int data = 666;
for(int i = 0; i < 2; i++)
{
for(int j = 0; j < 3; j++)
{
for(int k = 0; k < 4; k++)
{
(*ptr)[i][j][k].a = data++;
}
}
}
Step 4 : Free memory after use
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
free( tp[i][j] );
}
free( tp[i] );
}
free(tp);
See full program below
#include <stdio.h>
#include <stdlib.h>
struct ABC {
int a;
int b;
int c;
};
void fun(struct ABC ****ptr)
{
int data = 666;
for(int i = 0; i < 2; i++)
{
for(int j = 0; j < 3; j++)
{
for(int k = 0; k < 4; k++)
{
(*ptr)[i][j][k].a = data++;
(*ptr)[i][j][k].b = data++;
(*ptr)[i][j][k].c = data++;
}
}
}
}
int main(void)
{
struct ABC ***tp;
tp = malloc( 2 * sizeof(struct ABC **) );
for (int i = 0; i < 2; i++)
{
tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
for (int j = 0; j < 3; j++)
{
tp[i][j] = malloc( 4 * sizeof(struct ABC) );
}
}
int data = 1;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
for (int k = 0; k < 4; k++)
{
tp[i][j][k].a = data++;
tp[i][j][k].b = data++;
tp[i][j][k].c = data++;
}
}
}
printf("----- Before Call By Reference -----\n");
for(int i = 0; i < 2; i++)
{
for(int j = 0; j < 3; j++)
{
for(int k = 0; k < 4; k++)
{
printf("tp[%d][%d][%d].a = %d ", i, j, k, tp[i][j][k].a );
printf("tp[%d][%d][%d].b = %d ", i, j, k, tp[i][j][k].b );
printf("tp[%d][%d][%d].c = %d ", i, j, k, tp[i][j][k].c );
printf("\n");
}
printf("\n");
}
printf("\n");
}
fun(&tp);
printf("----- After Call By Reference -----\n");
for(int i = 0; i < 2; i++)
{
for(int j = 0; j < 3; j++)
{
for(int k = 0; k < 4; k++)
{
printf("tp[%d][%d][%d].a = %d ", i, j, k, tp[i][j][k].a );
printf("tp[%d][%d][%d].b = %d ", i, j, k, tp[i][j][k].b );
printf("tp[%d][%d][%d].c = %d ", i, j, k, tp[i][j][k].c );
printf("\n");
}
printf("\n");
}
printf("\n");
}
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
free( tp[i][j] );
}
free( tp[i] );
}
free(tp);
return 0;
}
Output is as below
----- Before Call By Reference -----
tp[0][0][0].a = 1 tp[0][0][0].b = 2 tp[0][0][0].c = 3
tp[0][0][1].a = 4 tp[0][0][1].b = 5 tp[0][0][1].c = 6
tp[0][0][2].a = 7 tp[0][0][2].b = 8 tp[0][0][2].c = 9
tp[0][0][3].a = 10 tp[0][0][3].b = 11 tp[0][0][3].c = 12
tp[0][1][0].a = 13 tp[0][1][0].b = 14 tp[0][1][0].c = 15
tp[0][1][1].a = 16 tp[0][1][1].b = 17 tp[0][1][1].c = 18
tp[0][1][2].a = 19 tp[0][1][2].b = 20 tp[0][1][2].c = 21
tp[0][1][3].a = 22 tp[0][1][3].b = 23 tp[0][1][3].c = 24
tp[0][2][0].a = 25 tp[0][2][0].b = 26 tp[0][2][0].c = 27
tp[0][2][1].a = 28 tp[0][2][1].b = 29 tp[0][2][1].c = 30
tp[0][2][2].a = 31 tp[0][2][2].b = 32 tp[0][2][2].c = 33
tp[0][2][3].a = 34 tp[0][2][3].b = 35 tp[0][2][3].c = 36
tp[1][0][0].a = 37 tp[1][0][0].b = 38 tp[1][0][0].c = 39
tp[1][0][1].a = 40 tp[1][0][1].b = 41 tp[1][0][1].c = 42
tp[1][0][2].a = 43 tp[1][0][2].b = 44 tp[1][0][2].c = 45
tp[1][0][3].a = 46 tp[1][0][3].b = 47 tp[1][0][3].c = 48
tp[1][1][0].a = 49 tp[1][1][0].b = 50 tp[1][1][0].c = 51
tp[1][1][1].a = 52 tp[1][1][1].b = 53 tp[1][1][1].c = 54
tp[1][1][2].a = 55 tp[1][1][2].b = 56 tp[1][1][2].c = 57
tp[1][1][3].a = 58 tp[1][1][3].b = 59 tp[1][1][3].c = 60
tp[1][2][0].a = 61 tp[1][2][0].b = 62 tp[1][2][0].c = 63
tp[1][2][1].a = 64 tp[1][2][1].b = 65 tp[1][2][1].c = 66
tp[1][2][2].a = 67 tp[1][2][2].b = 68 tp[1][2][2].c = 69
tp[1][2][3].a = 70 tp[1][2][3].b = 71 tp[1][2][3].c = 72
----- After Call By Reference -----
tp[0][0][0].a = 666 tp[0][0][0].b = 667 tp[0][0][0].c = 668
tp[0][0][1].a = 669 tp[0][0][1].b = 670 tp[0][0][1].c = 671
tp[0][0][2].a = 672 tp[0][0][2].b = 673 tp[0][0][2].c = 674
tp[0][0][3].a = 675 tp[0][0][3].b = 676 tp[0][0][3].c = 677
tp[0][1][0].a = 678 tp[0][1][0].b = 679 tp[0][1][0].c = 680
tp[0][1][1].a = 681 tp[0][1][1].b = 682 tp[0][1][1].c = 683
tp[0][1][2].a = 684 tp[0][1][2].b = 685 tp[0][1][2].c = 686
tp[0][1][3].a = 687 tp[0][1][3].b = 688 tp[0][1][3].c = 689
tp[0][2][0].a = 690 tp[0][2][0].b = 691 tp[0][2][0].c = 692
tp[0][2][1].a = 693 tp[0][2][1].b = 694 tp[0][2][1].c = 695
tp[0][2][2].a = 696 tp[0][2][2].b = 697 tp[0][2][2].c = 698
tp[0][2][3].a = 699 tp[0][2][3].b = 700 tp[0][2][3].c = 701
tp[1][0][0].a = 702 tp[1][0][0].b = 703 tp[1][0][0].c = 704
tp[1][0][1].a = 705 tp[1][0][1].b = 706 tp[1][0][1].c = 707
tp[1][0][2].a = 708 tp[1][0][2].b = 709 tp[1][0][2].c = 710
tp[1][0][3].a = 711 tp[1][0][3].b = 712 tp[1][0][3].c = 713
tp[1][1][0].a = 714 tp[1][1][0].b = 715 tp[1][1][0].c = 716
tp[1][1][1].a = 717 tp[1][1][1].b = 718 tp[1][1][1].c = 719
tp[1][1][2].a = 720 tp[1][1][2].b = 721 tp[1][1][2].c = 722
tp[1][1][3].a = 723 tp[1][1][3].b = 724 tp[1][1][3].c = 725
tp[1][2][0].a = 726 tp[1][2][0].b = 727 tp[1][2][0].c = 728
tp[1][2][1].a = 729 tp[1][2][1].b = 730 tp[1][2][1].c = 731
tp[1][2][2].a = 732 tp[1][2][2].b = 733 tp[1][2][2].c = 734
tp[1][2][3].a = 735 tp[1][2][3].b = 736 tp[1][2][3].c = 737
Other topics of structure and functions
Current Module
Previous Module
Next Module
Other Modules