Basics of Structure Single Pointers

In this section, you are going to learn

  • Step 1 : Define a variable and a pointer

struct ABC {
        int a;
        int b;
        int c;
};

struct ABC x = { .a = 1, .b = 2, .c = 3 };

struct ABC *ptr;
  • Step 2 : Pointer ptr points to variable x

ptr = &x;
  • Step 3 : Use *ptr to write to x

(*ptr).a = 100;
(*ptr).b = 200;
(*ptr).c = 300;
  • Step 4 : Use *ptr to read from x

printf("(*ptr).a = %d\n", (*ptr).a );
printf("(*ptr).b = %d\n", (*ptr).b );
printf("(*ptr).c = %d\n", (*ptr).c );
  • See full program below

#include <stdio.h>

struct ABC {
        int a;
        int b;
        int c;
};

int main(void)
{
        struct ABC x = { .a = 1, .b = 2, .c = 3 };
        struct ABC *ptr;
        ptr = &x;

        (*ptr).a = 100;
        (*ptr).b = 200;
        (*ptr).c = 300;

        printf("x.a = %d\n", x.a );
        printf("x.b = %d\n", x.b );
        printf("x.c = %d\n", x.c );

        printf("(*ptr).a = %d\n", (*ptr).a );
        printf("(*ptr).b = %d\n", (*ptr).b );
        printf("(*ptr).c = %d\n", (*ptr).c );

        return 0;
}
  • Output is as below

x.a = 100
x.b = 200
x.c = 300
(*ptr).a = 100
(*ptr).b = 200
(*ptr).c = 300
  • Step 1 : Define a variable and a pointer

struct ABC {
        int a;
        int b;
        int c;
};

struct ABC x = { .a = 1, .b = 2, .c = 3 };

struct ABC *ptr;
  • Step 2 : Pointer ptr points to variable x

ptr = &x;
  • Step 3 : Use ptr[0] to write to x

ptr[0].a = 100;
ptr[0].b = 200;
ptr[0].c = 300;
  • Step 4 : Use ptr[0] to read from x

printf("ptr[0].a = %d\n", ptr[0].a );
printf("ptr[0].b = %d\n", ptr[0].b );
printf("ptr[0].c = %d\n", ptr[0].c );
  • See full program below

#include <stdio.h>

struct ABC {
        int a;
        int b;
        int c;
};

int main(void)
{
        struct ABC x = { .a = 1, .b = 2, .c = 3 };
        struct ABC *ptr;
        ptr = &x;

        ptr[0].a = 100;
        ptr[0].b = 200;
        ptr[0].c = 300;

        printf("x.a = %d\n", x.a );
        printf("x.b = %d\n", x.b );
        printf("x.c = %d\n", x.c );

        printf("ptr[0].a = %d\n", ptr[0].a );
        printf("ptr[0].b = %d\n", ptr[0].b );
        printf("ptr[0].c = %d\n", ptr[0].c );

        return 0;
}
  • Output is as below

x.a = 100
x.b = 200
x.c = 300

ptr[0].a = 100
ptr[0].b = 200
ptr[0].c = 300
  • Step 1 : Define a variable and a pointer

struct ABC {
        int a;
        int b;
        int c;
};

struct ABC x = { .a = 1, .b = 2, .c = 3 };

struct ABC *ptr;
  • Step 2 : Pointer ptr points to variable x

ptr = &x;
  • Step 3 : Use ptr-> to write to x

ptr->a = 100;
ptr->b = 200;
ptr->c = 300;
  • Step 4 : Use ptr-> to read from x

printf("ptr->a = %d\n", ptr->a );
printf("ptr->b = %d\n", ptr->b );
printf("ptr->c = %d\n", ptr->c );
  • See full program below

#include <stdio.h>

struct ABC {
        int a;
        int b;
        int c;
};

int main(void)
{
        struct ABC x = { .a = 1, .b = 2, .c = 3 };
        struct ABC *ptr;
        ptr = &x;

        ptr->a = 100;
        ptr->b = 200;
        ptr->c = 300;

        printf("x.a = %d\n", x.a );
        printf("x.b = %d\n", x.b );
        printf("x.c = %d\n", x.c );

        printf("ptr->a = %d\n", ptr->a );
        printf("ptr->b = %d\n", ptr->b );
        printf("ptr->c = %d\n", ptr->c );

        return 0;
}
  • Output is as below

x.a = 100
x.b = 200
x.c = 300

ptr->a = 100
ptr->b = 200
ptr->c = 300
  • Step 1 : Define an array and a pointer

struct ABC {
        int a;
        int b;
        int c;
};

struct ABC arr[3] = {
        { .a = 1, .b = 2, .c = 3 },
        { .a = 10, .b = 20, .c = 30 },
        { .a = 100, .b = 200, .c = 300 },
};

struct ABC *ptr;
  • Step 2 : Let Single pointer to point to array

ptr = arr;

OR

ptr = &arr[0];
  • Step 3 : Access individual structures of array using ptr[ ] notation

ptr[2].a = 9;
ptr[2].b = 99;
ptr[2].c = 999;

printf("ptr[2].a = %d\n", ptr[2].a );
printf("ptr[2].b = %d\n", ptr[2].b );
printf("ptr[2].c = %d\n", ptr[2].c );

Note that, this is same as

(*( ptr + 2 )).a = 9;
(*( ptr + 2 )).b = 99;
(*( ptr + 2 )).c = 999;

printf(" (*( ptr + 2 )).a = %d\n", (*(ptr + 2)).a );
printf(" (*( ptr + 2 )).b = %d\n", (*(ptr + 2)).b );
printf(" (*( ptr + 2 )).c = %d\n", (*(ptr + 2)).c );

Note that, this is same as

arr[2].a = 9;
arr[2].b = 99;
arr[2].c = 999;

printf("arr[2].a = %d\n", arr[2].a);
printf("arr[2].b = %d\n", arr[2].b);
printf("arr[2].c = %d\n", arr[2].c);
  • Step 4 : Print full array using ptr

for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
        printf("ptr[%d].a = %d\n", i, ptr[i].a );
        printf("ptr[%d].b = %d\n", i, ptr[i].b );
        printf("ptr[%d].c = %d\n", i, ptr[i].c );
}
  • See full program below

#include <stdio.h>
#include <string.h>

struct ABC {
        int a;
        int b;
        int c;
};

int main(void)
{
        struct ABC arr[3] = {
                { .a = 1, .b = 2, .c = 3 },
                { .a = 10, .b = 20, .c = 30 },
                { .a = 100, .b = 200, .c = 300 },
        };

        struct ABC *ptr;

        ptr = arr;

        // Change individual structure using ptr[] notation
        ptr[2].a = 9;
        ptr[2].b = 99;
        ptr[2].c = 999;

        // Print individual structure using ptr[] notation
        printf("ptr[2].a = %d\n", ptr[2].a );
        printf("ptr[2].b = %d\n", ptr[2].b );
        printf("ptr[2].c = %d\n", ptr[2].c );

        // Print full array using "ptr[]" notation
        for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
        {
                printf("ptr[%d].a = %d\n", i, ptr[i].a );
                printf("ptr[%d].b = %d\n", i, ptr[i].b );
                printf("ptr[%d].c = %d\n", i, ptr[i].c );
        }

        // Change individual structure using *ptr notation
        (*( ptr + 2 )).a = 9;
        (*( ptr + 2 )).b = 99;
        (*( ptr + 2 )).c = 999;

        // Print individual structure using *ptr notation
        printf(" (*( ptr + 2 )).a = %d\n", (*(ptr + 2)).a );
        printf(" (*( ptr + 2 )).b = %d\n", (*(ptr + 2)).b );
        printf(" (*( ptr + 2 )).c = %d\n", (*(ptr + 2)).c );

        // Print full array using "*ptr" notation
        for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
        {
                printf(" (*( ptr + %d )).a = %d\n", i, (*(ptr + i)).a );
                printf(" (*( ptr + %d )).b = %d\n", i, (*(ptr + i)).b );
                printf(" (*( ptr + %d )).c = %d\n", i, (*(ptr + i)).c );
        }

        return 0;
}
  • Output is as below

ptr[2].a = 9
ptr[2].b = 99
ptr[2].c = 999

ptr[0].a = 1
ptr[0].b = 2
ptr[0].c = 3
ptr[1].a = 10
ptr[1].b = 20
ptr[1].c = 30
ptr[2].a = 9
ptr[2].b = 99
ptr[2].c = 999

(*( ptr + 2 )).a = 9
(*( ptr + 2 )).b = 99
(*( ptr + 2 )).c = 999

(*( ptr + 0 )).a = 1
(*( ptr + 0 )).b = 2
(*( ptr + 0 )).c = 3
(*( ptr + 1 )).a = 10
(*( ptr + 1 )).b = 20
(*( ptr + 1 )).c = 30
(*( ptr + 2 )).a = 9
(*( ptr + 2 )).b = 99
(*( ptr + 2 )).c = 999
  • Step 1 : Define a pointer ptr

struct ABC {
        int a;
        int b;
        int c;
};

struct ABC *ptr;
  • Step 2 : Allocate memory in heap and let ptr point to it

ptr = malloc(3 * sizeof(struct ABC));

This allocates 36 Bytes of memory in heap

  • Step 3 : memset and clear the memory before use

memset(ptr, 0, 3 * sizeof(struct ABC));

This is needed because, memory returned by malloc may have garbage contents !

  • Step 4 : Change individual structure using ptr[] notation

ptr[0].a = 1;
ptr[0].b = 11;
ptr[0].c = 111;
ptr[1].a = 2;
ptr[1].b = 22;
ptr[1].c = 222;
ptr[2].a = 3;
ptr[2].b = 33;
ptr[2].c = 333;
  • Step 5 : Print individual structure using ptr[] notation

printf("ptr[2].a = %d\n", ptr[2].a );
printf("ptr[2].b = %d\n", ptr[2].b );
printf("ptr[2].c = %d\n", ptr[2].c );
  • Step 6 : Print full array using “ptr[]” notation

for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
        printf("ptr[%d].a = %d\n", i, ptr[i].a );
        printf("ptr[%d].b = %d\n", i, ptr[i].b );
        printf("ptr[%d].c = %d\n", i, ptr[i].c );
}
  • Step 7 : Change individual structure using “*ptr” notation

(*( ptr + 0 )).a = 1;
(*( ptr + 0 )).b = 11;
(*( ptr + 0 )).c = 111;
(*( ptr + 1 )).a = 2;
(*( ptr + 1 )).b = 22;
(*( ptr + 1 )).c = 222;
(*( ptr + 2 )).a = 3;
(*( ptr + 2 )).b = 33;
(*( ptr + 2 )).c = 333;
  • Step 8 : Print individual structure using *ptr notation

printf(" (*( ptr + 2 )).a = %d\n", (*(ptr + 2)).a );
printf(" (*( ptr + 2 )).b = %d\n", (*(ptr + 2)).b );
printf(" (*( ptr + 2 )).c = %d\n", (*(ptr + 2)).c );
  • Step 9 : Print full array using “*ptr” notation

for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
        printf(" (*( ptr + %d )).a = %d\n", i, (*(ptr + i)).a );
        printf(" (*( ptr + %d )).b = %d\n", i, (*(ptr + i)).b );
        printf(" (*( ptr + %d )).c = %d\n", i, (*(ptr + i)).c );
}
  • Step 10 : Free memory after use

free(ptr);
  • See full program below

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct ABC {
        int a;
        int b;
        int c;
};

int main(void)
{
        struct ABC *ptr;

        ptr = malloc(3 * sizeof(struct ABC));

        memset(ptr, 0, 3 * sizeof(struct ABC));

        // Change individual structure using ptr[] notation
        ptr[0].a = 1;
        ptr[0].b = 11;
        ptr[0].c = 111;
        ptr[1].a = 2;
        ptr[1].b = 22;
        ptr[1].c = 222;
        ptr[2].a = 3;
        ptr[2].b = 33;
        ptr[2].c = 333;

        // Print individual structure using ptr[] notation
        printf("ptr[2].a = %d\n", ptr[2].a );
        printf("ptr[2].b = %d\n", ptr[2].b );
        printf("ptr[2].c = %d\n", ptr[2].c );

        // Print full array using "ptr[]" notation
        for (int i = 0; i < 3; i++)
        {
                printf("ptr[%d].a = %d\n", i, ptr[i].a );
                printf("ptr[%d].b = %d\n", i, ptr[i].b );
                printf("ptr[%d].c = %d\n", i, ptr[i].c );
        }

        // Change individual structure using *ptr notation
        (*( ptr + 0 )).a = 1;
        (*( ptr + 0 )).b = 11;
        (*( ptr + 0 )).c = 111;
        (*( ptr + 1 )).a = 2;
        (*( ptr + 1 )).b = 22;
        (*( ptr + 1 )).c = 222;
        (*( ptr + 2 )).a = 3;
        (*( ptr + 2 )).b = 33;
        (*( ptr + 2 )).c = 333;

        // Print individual structure using *ptr notation
        printf(" (*( ptr + 2 )).a = %d\n", (*(ptr + 2)).a );
        printf(" (*( ptr + 2 )).b = %d\n", (*(ptr + 2)).b );
        printf(" (*( ptr + 2 )).c = %d\n", (*(ptr + 2)).c );

        // Print full array using "*ptr" notation
        for (int i = 0; i < 3; i++)
        {
                printf(" (*( ptr + %d )).a = %d\n", i, (*(ptr + i)).a );
                printf(" (*( ptr + %d )).b = %d\n", i, (*(ptr + i)).b );
                printf(" (*( ptr + %d )).c = %d\n", i, (*(ptr + i)).c );
        }

        free(ptr);

        return 0;
}
  • Output is as below

ptr[2].a = 3
ptr[2].b = 33
ptr[2].c = 333

ptr[0].a = 1
ptr[0].b = 11
ptr[0].c = 111
ptr[1].a = 2
ptr[1].b = 22
ptr[1].c = 222
ptr[2].a = 3
ptr[2].b = 33
ptr[2].c = 333

(*( ptr + 2 )).a = 3
(*( ptr + 2 )).b = 33
(*( ptr + 2 )).c = 333

(*( ptr + 0 )).a = 1
(*( ptr + 0 )).b = 11
(*( ptr + 0 )).c = 111
(*( ptr + 1 )).a = 2
(*( ptr + 1 )).b = 22
(*( ptr + 1 )).c = 222
(*( ptr + 2 )).a = 3
(*( ptr + 2 )).b = 33
(*( ptr + 2 )).c = 333
  • Step 1 : Define an array and a pointer

struct ABC {
        int a;
        int b;
        int c;
};

struct ABC arr[3] = {
        { .a = 1, .b = 2, .c = 3 },
        { .a = 10, .b = 20, .c = 30 },
        { .a = 100, .b = 200, .c = 300 },
};

struct ABC *ptr;
  • Step 2 : Let Single pointer to point to array

ptr = arr + 1;

OR

ptr = &arr[0] + 1;

With this ptr is pointing at index 1

  • Step 3 : Access Bytes in forward direction

Observe that, ptr can access in total of 1 index in forward direction with respect to it’s current location

ptr[0] is equal to arr[1]

OR

*ptr is equal to arr[1]

  • Step 4 : Access Bytes in backward direction

Observe that, ptr can access in total of 1 index in backward direction with respect to it’s current location

ptr[-1] is equal to arr[0]

  • See full program below

#include <stdio.h>

struct ABC {
        int a;
        int b;
        int c;
};

int main(void)
{
        struct ABC arr[3] = {
                { .a = 1, .b = 2, .c = 3 },
                { .a = 10, .b = 20, .c = 30 },
                { .a = 100, .b = 200, .c = 300 },
        };

        struct ABC *ptr;

        ptr = arr + 1;

        printf("------ Printing structures using ptr[] notation ------\n");
        printf("ptr[-1].a = %d\n", ptr[-1].a);
        printf("ptr[-1].b = %d\n", ptr[-1].b);
        printf("ptr[-1].c = %d\n", ptr[-1].c);

        printf("ptr[0].a = %d\n", ptr[0].a);
        printf("ptr[0].b = %d\n", ptr[0].b);
        printf("ptr[0].c = %d\n", ptr[0].c);

        printf("ptr[1].a = %d\n", ptr[1].a);
        printf("ptr[1].b = %d\n", ptr[1].b);
        printf("ptr[1].c = %d\n", ptr[1].c);

        printf("------ Printing structures using *ptr notation ------\n");
        printf("(*(ptr - 1)).a = %d\n", (*(ptr - 1)).a );
        printf("(*(ptr - 1)).b = %d\n", (*(ptr - 1)).b );
        printf("(*(ptr - 1)).c = %d\n", (*(ptr - 1)).c );

        printf("(*ptr).a = %d\n", (*ptr).a );
        printf("(*ptr).b = %d\n", (*ptr).b );
        printf("(*ptr).c = %d\n", (*ptr).c );

        printf("(*(ptr + 1)).a = %d\n", (*(ptr + 1)).a );
        printf("(*(ptr + 1)).b = %d\n", (*(ptr + 1)).b );
        printf("(*(ptr + 1)).c = %d\n", (*(ptr + 1)).c );

        return 0;
}
  • Output is as below

------ Printing structures using ptr[] notation ------
ptr[-1].a = 1
ptr[-1].b = 2
ptr[-1].c = 3
ptr[0].a = 10
ptr[0].b = 20
ptr[0].c = 30
ptr[1].a = 100
ptr[1].b = 200
ptr[1].c = 300

------ Printing structures using *ptr notation ------
(*(ptr - 1)).a = 1
(*(ptr - 1)).b = 2
(*(ptr - 1)).c = 3
(*ptr).a = 10
(*ptr).b = 20
(*ptr).c = 30
(*(ptr + 1)).a = 100
(*(ptr + 1)).b = 200
(*(ptr + 1)).c = 300

Rules of Single Pointer Arithmetic

  • Single Pointer CAN BE Incremented

  • Incrementing a Single Pointer takes it to next immediate accessible Unit

  • Single Pointer CAN BE Decremented

  • Decrementing a Single Pointer takes it to previous immediate accessible Unit

  • Single Pointer CAN NOT BE used in Division

  • Single Pointer CAN NOT BE used in Multiplication

  • Two single pointers CAN BE subtracted

  • Two single pointers CAN NOT BE added

  • Two single pointers CAN NOT BE divided

  • Two single pointers CAN NOT BE multiplied

  • Step 1 : Define an array

struct ABC {
        int a;
        int b;
        int c;
};
  • Step 2 : Let ptr point to array arr

struct ABC arr[3] = {
        { .a = 1, .b = 2, .c = 3 },
        { .a = 10, .b = 20, .c = 30 },
        { .a = 100, .b = 200, .c = 300 },
};

struct ABC *ptr;

ptr = arr;
  • Step 3 : Increment ptr twice

ptr++;
ptr++;

OR

ptr += 2;

ptr is now pointing to Index 2

  • Step 4 : Print the contents of structure object at index 2 using *ptr notation

printf("(*ptr).a = %d\n", (*ptr).a );
printf("(*ptr).b = %d\n", (*ptr).b );
printf("(*ptr).c = %d\n", (*ptr).c );
  • See full program below

#include <stdio.h>

struct ABC {
        int a;
        int b;
        int c;
};

int main(void)
{
        struct ABC arr[3] = {
                { .a = 1, .b = 2, .c = 3 },
                { .a = 10, .b = 20, .c = 30 },
                { .a = 100, .b = 200, .c = 300 },
        };

        struct ABC *ptr;

        ptr = arr;

        ptr = arr;

        ptr++;

        ptr++;

        // ptr is now at Index 2

        printf("(*ptr).a = %d\n", (*ptr).a );
        printf("(*ptr).b = %d\n", (*ptr).b );
        printf("(*ptr).c = %d\n", (*ptr).c );

        return 0;
}
  • Output is as below

(*ptr).a = 100
(*ptr).b = 200
(*ptr).c = 300
  • Step 1 : Define an array

struct ABC {
        int a;
        int b;
        int c;
};

struct ABC arr[3] = {
        { .a = 1, .b = 2, .c = 3 },
        { .a = 10, .b = 20, .c = 30 },
        { .a = 100, .b = 200, .c = 300 },
};
  • Step 2 : Let ptr point to array arr

struct ABC *ptr;

ptr = arr + sizeof(arr)/sizeof(arr[0]) - 1;
  • Step 3 : Decrement ptr twice

ptr--;
ptr--;

OR

ptr -= 2;

ptr is now pointing to Index 0

  • Step 4 : Print the contents of structure object at index 0 using *ptr notation

printf("(*ptr).a = %d\n", (*ptr).a );
printf("(*ptr).b = %d\n", (*ptr).b );
printf("(*ptr).c = %d\n", (*ptr).c );
  • See full program below

#include <stdio.h>

struct ABC {
        int a;
        int b;
        int c;
};

int main(void)
{
        struct ABC arr[3] = {
                { .a = 1, .b = 2, .c = 3 },
                { .a = 10, .b = 20, .c = 30 },
                { .a = 100, .b = 200, .c = 300 },
        };

        struct ABC *ptr;

        ptr = arr + sizeof(arr)/sizeof(arr[0]) - 1;

        ptr--;

        ptr--;

        //ptr is now at Index 0
        printf("(*ptr).a = %d\n", (*ptr).a );
        printf("(*ptr).b = %d\n", (*ptr).b );
        printf("(*ptr).c = %d\n", (*ptr).c );

        return 0;
}
  • Output is as below

(*ptr).a = 1
(*ptr).b = 2
(*ptr).c = 3
  • Step 1 : Define an array

struct ABC {
        int a;
        int b;
        int c;
};

struct ABC arr[3] = {
        { .a = 1, .b = 2, .c = 3 },
        { .a = 10, .b = 20, .c = 30 },
        { .a = 100, .b = 200, .c = 300 },
};
  • Step 2 : Let ptr point to array arr

struct ABC *ptr;

ptr = arr;
  • Step 3 : Increment ptr twice

ptr = ptr / 2;

This is INVALID

  • See full program below

#include <stdio.h>

struct ABC {
        int a;
        int b;
        int c;
};

int main(void)
{
        struct ABC arr[3] = {
                { .a = 1, .b = 2, .c = 3 },
                { .a = 10, .b = 20, .c = 30 },
                { .a = 100, .b = 200, .c = 300 },
        };

        struct ABC *ptr;

        ptr = arr;

        ptr = ptr / 2;

        return 0;
}
  • Output is as below

p9_struct_sp.c: In function "main":
p9_struct_sp.c:21:19: error: invalid operands to binary / (have "struct ABC *" and "int")
   21 |         ptr = ptr / 2;

Note the compilation error !

  • Step 1 : Define an array

struct ABC {
        int a;
        int b;
        int c;
};

struct ABC arr[3] = {
        { .a = 1, .b = 2, .c = 3 },
        { .a = 10, .b = 20, .c = 30 },
        { .a = 100, .b = 200, .c = 300 },
};
  • Step 2 : Let ptr point to array arr

struct ABC *ptr;

ptr = arr;
  • Step 3 : Increment ptr twice

ptr = ptr * 2;

This is INVALID

  • See full program below

#include <stdio.h>

struct ABC {
        int a;
        int b;
        int c;
};

int main(void)
{
        struct ABC arr[3] = {
                { .a = 1, .b = 2, .c = 3 },
                { .a = 10, .b = 20, .c = 30 },
                { .a = 100, .b = 200, .c = 300 },
        };

        struct ABC *ptr;

        ptr = arr;

        ptr = ptr * 2;

        return 0;
}
  • Output is as below

p10_struct_sp.c: In function "main":
p10_struct_sp.c:21:19: error: invalid operands to binary * (have "struct ABC *" and "int")
   21 |         ptr = ptr * 2;

Note the compilation error !