Pointer to a Single Dimension Array of Structures
In this section, you are going to learn
How to define and use Pointer to Single Dimension Arrays ?
Pointer to an Array
Pointer to an array : Passed as function arguement : Call by Value
Pointer to an array : Passed as function arguement : Call by Reference
Method 1 : Pointer to an array : How to print contents of single dimension array ?
Method 2 : Pointer to an array : How to print contents of single dimension array ?
Pointer to an array : Pointing to Single dimension array inside a Double dimension array
type ( *ptr ) [ size_of_array ];
An example is as below
struct ABC a[3] = {
{.a = 1, .b = 2},
{.a = 3, .b = 4},
{.a = 5, .b = 6}
};
struct ABC (*ptr)[3];
ptr = &a;
Pointer to an Array when incremented, increments by size of the array to which it is pointing to !
Pointer to an Array when decremented, decrements by size of the array to which it is pointing to !
Let us see how it is done. See below
Step 1 : Define a single dimension array
struct ABC {
int a;
int b;
};
struct ABC a[3] = {
{.a = 1, .b = 2},
{.a = 3, .b = 4},
{.a = 5, .b = 6}
};
Step 2 : Define a pointer to an array
struct ABC (*ptr)[3];
Step 3 : Let pointer to an array, point to single dimension array
ptr = &a;
Step 4 : Check pointer arithmetic
printf("Before Increment : ptr = %lx\n", (unsigned long int) ptr);
ptr++;
printf("After Increment : ptr = %lx\n", (unsigned long int) ptr);
See full program below
#include <stdio.h>
struct ABC {
int a;
int b;
};
int main(void)
{
struct ABC a[3] = {
{.a = 1, .b = 2},
{.a = 3, .b = 4},
{.a = 5, .b = 6}
};
struct ABC (*ptr)[3];
ptr = &a;
printf("Before Increment : ptr = %lx\n", (unsigned long int) ptr);
ptr++;
printf("After Increment : ptr = %lx\n", (unsigned long int) ptr);
return 0;
}
Output is as below
Before Increment : ptr = 7ffda2b55830
After Increment : ptr = 7ffda2b55848
Observe that difference is 24 !
sizeof(a)
is 24 Bytes
ptr
is pointer to an array of 3 structure objects with size of 24 Bytes
When Pointer to an Array is passed as argument, Prototype of function should match the type properly !
Let us see how it is done. See below
Step 1 : Define a single dimension array
struct ABC {
int a;
int b;
};
struct ABC a[3] = {
{.a = 1, .b = 2},
{.a = 3, .b = 4},
{.a = 5, .b = 6}
};
Step 2 : Define a pointer to an array
struct ABC (*ptr)[3];
Step 3 : Let pointer to an array, point to single dimension array
ptr = &a;
Step 4 : Pass
ptr
as argument to functionfun
fun(ptr);
Step 5 : Define function
fun
void fun( struct ABC (*p)[3] )
{
}
See full program below
#include <stdio.h>
struct ABC {
int a;
int b;
};
void fun( struct ABC (*p)[3] )
{
}
int main(void)
{
struct ABC a[3] = {
{.a = 1, .b = 2},
{.a = 3, .b = 4},
{.a = 5, .b = 6}
};
struct ABC (*ptr)[3];
ptr = &a;
fun(ptr);
return 0;
}
When Pointer to an Array is passed as argument by call by reference, Prototype of function should match the type properly !
Let us see how it is done. See below
Step 1 : Define a Double dimension array
struct ABC a[2][3] = {
{
{.a = 1, .b = 2},
{.a = 3, .b = 4},
{.a = 5, .b = 6}
},
{
{.a = 100, .b = 200},
{.a = 300, .b = 400},
{.a = 500, .b = 600}
},
};
Step 2 : Define a pointer to an array
struct ABC (*ptr)[3];
Step 3 : Let pointer to an array, point to single dimension array
ptr = &a[0];
Step 4 : Pass
ptr
as argument to functionfun
. Call by reference
fun(&ptr);
Step 5 : Define function
fun
void fun(struct ABC (**p)[3])
{
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
printf("(*p)[%d][%d].a = %d ", i, j, (*p)[i][j].a);
printf("(*p)[%d][%d].b = %d ", i, j, (*p)[i][j].b);
printf("\n");
}
printf("\n");
}
}
This is easy to understand ! Let us derive the rules
Rule 1 : Base rule in
main
ptr = &a[0];
Rule 2 : Base rule in
fun
p = &ptr
Rule 2 : Move & from RHS to LHS. This becomes * on LHS
*p = ptr
Rule 3 : Replace
ptr
referring to Rule 1
*p = &a[0]
Rule 4 : Move & from RHS to LHS. This becomes * on LHS
**p = a[0]
Rule 5 :
*
and[ ]
can be used interchangeably
(*p)[0] = a[0]
Rule 6 :
*
and[ ]
can be used interchangeably
p[0][0] = a[0]
Rule 7 :
*
and[ ]
can be used interchangeably
p[0][0] = &a[0][0]
Rule 8 : Move & from RHS to LHS. This becomes * on LHS
(*p)[0][0] = a[0][0]
Rule 9 : Extending Rule 8
(*p)[i][j] = a[i][j]
See full program below
#include <stdio.h>
struct ABC {
int a;
int b;
};
void fun(struct ABC (**p)[3])
{
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
printf("(*p)[%d][%d].a = %d ", i, j, (*p)[i][j].a);
printf("(*p)[%d][%d].b = %d ", i, j, (*p)[i][j].b);
printf("\n");
}
printf("\n");
}
}
int main(void)
{
struct ABC a[2][3] = {
{
{.a = 1, .b = 2},
{.a = 3, .b = 4},
{.a = 5, .b = 6}
},
{
{.a = 100, .b = 200},
{.a = 300, .b = 400},
{.a = 500, .b = 600}
},
};
struct ABC (*ptr)[3];
ptr = &a[0];
fun(&ptr);
return 0;
}
Output is as below
(*p)[0][0].a = 1 (*p)[0][0].b = 2
(*p)[0][1].a = 3 (*p)[0][1].b = 4
(*p)[0][2].a = 5 (*p)[0][2].b = 6
(*p)[1][0].a = 100 (*p)[1][0].b = 200
(*p)[1][1].a = 300 (*p)[1][1].b = 400
(*p)[1][2].a = 500 (*p)[1][2].b = 600
We can use pointer to an array directly inorder to print the contents of array to which it is pointing to !
Let us see how it is done. See below
Step 1 : Define a single dimension array
struct ABC {
int a;
int b;
};
struct ABC a[3] = {
{.a = 1, .b = 2},
{.a = 3, .b = 4},
{.a = 5, .b = 6}
};
Step 2 : Define a pointer to an array
struct ABC (*ptr)[3];
Step 3 : Let pointer to an array, point to single dimension array
ptr = &a;
We can derive other rules from this base rule !
Rule 1 : Base rule
ptr = &a;
Rule 2 : Move
&
from RHS to LHS. This becomes*
on LHS
*ptr = a
Rule 3 :
a
is also equals to&a[0]
*ptr = &a[0]
Rule 4 :
*ptr
is equal toptr[0]
ptr[0] = &a[0]
Rule 5 : Move
&
from RHS to LHS. This becomes*
on LHS
(*ptr)[0] = a[0]
Rule 6 :
(*ptr)[0]
is equal toptr[0][0]
ptr[0][0] = a[0]
Rule 7 : Extending Rule 5
(*ptr)[i] = a[i]
Step 4 : Access individual structures using
(*ptr)[i]
for (int i = 0; i < 3; i++) {
printf("a = %d ", (*ptr)[i].a);
printf("b = %d ", (*ptr)[i].b);
printf("\n");
}
See full program below
#include <stdio.h>
struct ABC {
int a;
int b;
};
int main(void)
{
struct ABC a[3] = {
{.a = 1, .b = 2},
{.a = 3, .b = 4},
{.a = 5, .b = 6}
};
struct ABC (*ptr)[3];
ptr = &a;
for (int i = 0; i < 3; i++) {
printf("a = %d ", (*ptr)[i].a);
printf("b = %d ", (*ptr)[i].b);
printf("\n");
}
return 0;
}
Output is as below
a = 1 b = 2
a = 3 b = 4
a = 5 b = 6
We can use pointer to an array directly inorder to print the contents of array to which it is pointing to !
Let us see how it is done. See below
Step 1 : Define a single dimension array
struct ABC {
int a;
int b;
};
struct ABC a[3] = {
{.a = 1, .b = 2},
{.a = 3, .b = 4},
{.a = 5, .b = 6}
};
Step 2 : Pass address of array
a
as an argument to functionfun
fun(&a, sizeof(a) / sizeof(a[0]) );
Step 3 : Define function
fun
void fun(struct ABC (*p)[3], int size)
{
}
Note the function definition !
Since first argument is passed as address of array
a
, prototype must have pointer to an array in first parameter
Step 4 : Let us write the code to access individual structures of single dimension array inside function
fun
void fun(struct ABC (*p)[3], int size)
{
for (int i = 0; i < size; i++) {
printf("(*p)[%d].a = %d\n", i, (*p)[i].a);
printf("(*p)[%d].b = %d\n", i, (*p)[i].b);
}
for (int i = 0; i < size; i++) {
printf("p[0][%d].a = %d\n", i, p[0][i].a);
printf("p[0][%d].b = %d\n", i, p[0][i].b);
}
}
This is easy to understand ! Let us derive the rules
Rule 1 : Base rule
p = &a
Where,
LHS
p
is a variable on stack of function funfun
RHS
&a
is actual argument passed to functionfun
Rule 2 : Move
&
from RHS to LHS. This becomes*
on LHS
*p = a
Rule 3 : a is also equals to &a[0]
*p = &a[0]
Rule 4 : Move
&
from RHS to LHS. This becomes*
on LHS
**p = a[0]
Rule 5 :
*
and[ ]
can be used interchangeably
(*p)[0] = a[0]
Rule 6 :
*
and[ ]
can be used interchangeably
p[0][0] = a[0]
Rule 7 : Extending Rule 5
(*p)[i] = a[i]
Rule 8 : Extending Rule 5
p[0][i] = a[i]
See full program below
#include <stdio.h>
struct ABC {
int a;
int b;
};
void fun(struct ABC (*p)[3], int size)
{
for (int i = 0; i < size; i++) {
printf("(*p)[%d].a = %d\n", i, (*p)[i].a);
printf("(*p)[%d].b = %d\n", i, (*p)[i].b);
}
for (int i = 0; i < size; i++) {
printf("p[0][%d].a = %d\n", i, p[0][i].a);
printf("p[0][%d].b = %d\n", i, p[0][i].b);
}
}
int main(void)
{
struct ABC a[3] = {
{.a = 1, .b = 2},
{.a = 3, .b = 4},
{.a = 5, .b = 6}
};
fun(&a, sizeof(a) / sizeof(a[0]) );
return 0;
}
Output is as below
(*p)[0].a = 1
(*p)[0].b = 2
(*p)[1].a = 3
(*p)[1].b = 4
(*p)[2].a = 5
(*p)[2].b = 6
p[0][0].a = 1
p[0][0].b = 2
p[0][1].a = 3
p[0][1].b = 4
p[0][2].a = 5
p[0][2].b = 6
Step 1 : Define a double dimension array of structures
struct ABC a[2][3] = {
{
{.a = 1, .b = 2},
{.a = 3, .b = 4},
{.a = 5, .b = 6}
},
{
{.a = 100, .b = 200},
{.a = 300, .b = 400},
{.a = 500, .b = 600}
},
};
Step 2 : Define a pointer to an array of single dimension
struct ABC (*ptr)[3];
Step 3 : Let the pointer to point to Single dimension array inside a Double dimension array
ptr = &a[0];
See full program below
#include <stdio.h>
struct ABC {
int a;
int b;
};
int main(void)
{
struct ABC a[2][3] = {
{
{.a = 1, .b = 2},
{.a = 3, .b = 4},
{.a = 5, .b = 6}
},
{
{.a = 100, .b = 200},
{.a = 300, .b = 400},
{.a = 500, .b = 600}
},
};
struct ABC (*ptr)[3];
ptr = &a[0];
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
printf("ptr[%d][%d].a = %d\n", i, j, ptr[i][j].a);
printf("ptr[%d][%d].b = %d\n", i, j, ptr[i][j].b);
}
}
return 0;
}
Output is as below
ptr[0][0].a = 1
ptr[0][0].b = 2
ptr[0][1].a = 3
ptr[0][1].b = 4
ptr[0][2].a = 5
ptr[0][2].b = 6
ptr[1][0].a = 100
ptr[1][0].b = 200
ptr[1][1].a = 300
ptr[1][1].b = 400
ptr[1][2].a = 500
ptr[1][2].b = 600
Step 1 : Allocate a block of memory in Heap
struct ABC *a;
a = malloc(6 * sizeof(struct ABC));
Step 2 : Assign User Data in Heap memory
memset(a, 0xaa, 6 * sizeof(struct ABC));
Step 3 : Let
ptr
point to block of memory in Heap
struct ABC (*ptr)[3];
ptr = (struct ABC (*)[3]) a;
Note that typecasting done !
Key is to remember that, ptr
should point to block of continuous memory for it to access User data properly !
Step 4 : Method 1 : Access the memory block in Heap using
ptr
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
printf("ptr[%d][%d].a = %x\n", i, j, ptr[i][j].a);
printf("ptr[%d][%d].b = %x\n", i, j, ptr[i][j].b);
}
}
Step 5 : Method 2 : Access the memory block in Heap using
ptr
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
printf("*ptr->a = %x\n", (*ptr)->a);
printf("*ptr->b = %x\n", (*ptr)->b);
}
ptr++;
}
Remember after Step 5, ptr
is NOT pointing to start of Heap !
Step 6 : Free Heap memory after use
free(a);
See full program below
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct ABC {
int a;
int b;
};
int main(void)
{
struct ABC *a;
struct ABC (*ptr)[3];
a = malloc(6 * sizeof(struct ABC));
memset(a, 0xaa, 6 * sizeof(struct ABC));
ptr = (struct ABC (*)[3])a;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
printf("ptr[%d][%d].a = %x\n", i, j, ptr[i][j].a);
printf("ptr[%d][%d].b = %x\n", i, j, ptr[i][j].b);
}
}
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
printf("*ptr->a = %x\n", (*ptr)->a);
printf("*ptr->b = %x\n", (*ptr)->b);
}
ptr++;
}
free(a);
return 0;
}
Output is as below
ptr[0][0].a = aaaaaaaa
ptr[0][0].b = aaaaaaaa
ptr[0][1].a = aaaaaaaa
ptr[0][1].b = aaaaaaaa
ptr[0][2].a = aaaaaaaa
ptr[0][2].b = aaaaaaaa
ptr[1][0].a = aaaaaaaa
ptr[1][0].b = aaaaaaaa
ptr[1][1].a = aaaaaaaa
ptr[1][1].b = aaaaaaaa
ptr[1][2].a = aaaaaaaa
ptr[1][2].b = aaaaaaaa
*ptr->a = aaaaaaaa
*ptr->b = aaaaaaaa
*ptr->a = aaaaaaaa
*ptr->b = aaaaaaaa
*ptr->a = aaaaaaaa
*ptr->b = aaaaaaaa
*ptr->a = aaaaaaaa
*ptr->b = aaaaaaaa
*ptr->a = aaaaaaaa
*ptr->b = aaaaaaaa
*ptr->a = aaaaaaaa
*ptr->b = aaaaaaaa
Current Module
Previous Module
Next Module
Other Modules