CS Atlas GATE 2027
PDS course
0 / 103 complete

PDS/Phase 1 · Programming in C

Lesson 1.6 · Item 29 of 103

Structures, unions, typedef; self-referential structures; structure size and padding

Read at your own pace. Try the questions before opening the answers.

On this page

0 · Recall Warm-up

Answer from memory first. Answers are in the Answer Vault at the bottom.

  • How many bytes does char s[] = "GATE" occupy? from Lesson 1.5.3
  • Why can a function change the elements of an array passed to it? from Lesson 1.5.1
  • What does each call push onto the call stack? from Lesson 1.3.3

1 · The Hook

🎣

A railway reservation has a PNR number, a passenger name, a coach letter and a fare. Keeping four separate arrays (pnr[], name[], coach[], fare[]) in step is error-prone. A structure bundles the four into one record, the way a single ticket holds all four details.

2 · Predict First

🤔

What is sizeof of struct { char c; int i; } on our machine: 5 or something else? Make a guess in your head. The answer opens Section 3.

3 · Core Concept

💡

Predict First — the answer

8. The compiler places the int at an offset that is a multiple of 4, so 3 unused padding bytes follow c.

Defining and using a structure

struct student {
    int roll;
    char grade;
    float marks;
};

int main(void)
{
    struct student a = {7, 'A', 92.5f};
    struct student b = a;          /* copies every member */
    b.roll = 8;
    struct student *p = &a;
    p->marks = 95.0f;              /* same as (*p).marks */
    printf("%d %c %.1f | %d %.1f\n", a.roll, a.grade, a.marks, b.roll, b.marks);
    return 0;
}

Output

7 A 95.0 | 8 92.5
  • struct student { … }; defines a new type; the parts are members.
  • Members are reached with the dot: a.roll. Through a pointer use the arrow: p->marks means (*p).marks.
  • Structures can be initialized with a list and assigned as a whole (every member is copied) — unlike arrays. They cannot be compared with ==.

Structures and functions

A structure argument is copied like any value (call by value); pass its address to let the function change it.

struct point { int x, y; };

void moveCopy(struct point p) { p.x += 10; }
void movePtr(struct point *p) { p->x += 10; }

int main(void)
{
    struct point a = {1, 2};
    moveCopy(a);
    printf("%d ", a.x);
    movePtr(&a);
    printf("%d\n", a.x);
    return 0;
}

Output

1 11

typedef

typedef gives a new name to an existing type: typedef unsigned int uint; or, commonly, typedef struct { … } Person; so that variables are declared as Person p;.

typedef struct {
    char name[8];
    int age;
} Person;

int main(void)
{
    Person team[2] = {{"Asha", 21}, {"Ravi", 23}};
    Person *p = team;
    p++;
    printf("%s %d %u\n", p->name, (p - 1)->age, sizeof(team));
    return 0;
}

Output

Ravi 21 24

Arrays of structures and pointer arithmetic work as usual: p + 1 jumps one whole structure (12 bytes here: an 8-character name plus a 4-byte int).

Self-referential structures

A structure cannot contain itself (it would be infinitely big), but it can contain a pointer to its own type. That lets records point to each other and form chains:

struct link {
    int value;
    struct link *next;
};

int main(void)
{
    struct link c = {30, NULL};
    struct link b = {20, &c};
    struct link a = {10, &b};
    printf("%d %d %d\n", a.value, a.next->value, a.next->next->value);
    printf("%u\n", sizeof(struct link));
    return 0;
}

Output

10 20 30
8

Size and padding

Assume each member must start at an offset that is a multiple of its own size, and the total is rounded up to a multiple of the largest member. Unused bytes are padding.

struct A { char c; int i; };
struct B { char a; char b; int i; };
struct C { char a; int i; char b; };
struct D { double d; char c; };

int main(void)
{
    printf("%u %u %u %u\n", sizeof(struct A), sizeof(struct B), sizeof(struct C), sizeof(struct D));
    return 0;
}

Output

8 8 12 16

struct C wastes 6 bytes; reordering members from largest to smallest minimizes padding. Real compilers follow these rules on most machines, but alignment is machine-dependent: questions state their assumptions.

Unions

A union looks like a structure, but all members share the same memory: its size is the largest member, rounded up for alignment. Only one member holds a meaningful value at a time.

union value {
    int i;
    char c[5];
};

int main(void)
{
    union value v;
    v.i = 65;
    printf("%u %c\n", sizeof(v), v.c[0]);
    return 0;
}

Output

8 A

c[5] needs 5 bytes, rounded up to a multiple of 4 (the int’s alignment) = 8. Storing 65 in v.i and reading v.c[0] gives 'A' here because this machine stores the lowest byte first; reading a different member from the one last written depends on the machine.

4 · Visual

struct C { char a; int i; char b; }   -> 12 bytes

 offset:  0    1    2    3    4    5    6    7    8    9   10   11
        [ a ][pad][pad][pad][ i  ][ i  ][ i  ][ i  ][ b  ][pad][pad][pad]

struct B { char a; char b; int i; }   -> 8 bytes

 offset:  0    1    2    3    4    5    6    7
        [ a ][ b ][pad][pad][ i  ][ i  ][ i  ][ i  ]

union { int i; char c[5]; }          -> 8 bytes: all members start at offset 0
        [i/c0][i/c1][i/c2][i/c3][ c4 ][pad][pad][pad]

Members are placed at multiples of their size; a union overlays its members.

Diagram: a · a: 10 · • · &a · b: 20 · • · &b · c: 30 · • · &c · NULL

Three struct link records chained through their next pointers; the last next is NULL.

5 · Worked Examples

Example 1 Easy

What does this print?

struct point { int x, y; };

void moveCopy(struct point p) { p.x += 10; }
void movePtr(struct point *p) { p->x += 10; }

int main(void)
{
    struct point a = {1, 2};
    moveCopy(a);
    printf("%d ", a.x);
    movePtr(&a);
    printf("%d\n", a.x);
    return 0;
}

Solution

moveCopy works on a copy, so a.x stays 1. movePtr writes through the pointer: 11.

Output

1 11

Example 2 Medium

With the alignment rule above, what are the sizes of struct { char a; double d; } and struct { int x; char c; short s; }?

Solution

First: a at 0, d at 8 (multiple of 8), total 16. Second: x at 0–3, c at 4, s at 6–7 (multiple of 2), total 8 (already a multiple of 4).

Example 3 GATE

What does this print?

struct item {
    char code;
    double price;
    short qty;
};

int main(void)
{
    struct item arr[3];
    struct item *p = arr;
    printf("%u %d\n", sizeof(struct item), (int)((char *)(p + 2) - (char *)p));
    return 0;
}

Solution

code at 0; price at 8 (multiple of 8); qty at 16–17; total 18 rounded up to a multiple of 8 = 24. p + 2 jumps 2 × 24 = 48 bytes.

Output

24 48

6 · GATE Traps

⚠️

  • sizeof(struct) is often larger than the sum of the members (padding).
  • Member order changes the size: put large members first.
  • p->m means (*p).m; *p.m means *(p.m), a different thing.
  • Structures are passed and assigned by copying; arrays inside them are copied too.
  • A union is as big as its largest member (plus alignment), not the sum.
  • A structure may contain a pointer to its own type, never itself.

8 · Memory Hook

🧠

“A struct is a ticket, a union is a locker.” The ticket has a separate box for every detail; the locker has one space that holds whichever item you put in last.

9 · Connect the Dots

So far every variable, array and structure had a size fixed when the program was written, and lived in a frame or the static area. A chain of self-referential records should be able to grow while the program runs. Next lesson answers: how does a program ask for new memory while it runs, and give it back?

10 · Self-Test

GATE format. Try every question before opening the vault.

Q1MCQ2 marksOutput

What does this print?

struct student {
    int roll;
    char grade;
    float marks;
};

int main(void)
{
    struct student a = {7, 'A', 92.5f};
    struct student b = a;          /* copies every member */
    b.roll = 8;
    struct student *p = &a;
    p->marks = 95.0f;              /* same as (*p).marks */
    printf("%d %c %.1f | %d %.1f\n", a.roll, a.grade, a.marks, b.roll, b.marks);
    return 0;
}
  • (A) 7 A 92.5 | 8 95.0
  • (B) 8 A 95.0 | 8 92.5
  • (C) 7 A 95.0 | 8 92.5
  • (D) 7 A 95.0 | 8 95.0

Q2NAT2 marksPadding

Under the rule “each member at a multiple of its size, total a multiple of the largest member”, what is the size of struct { char a; int b; char c; double d; }?

Numerical answer: ________

Q3MCQ1 markUnion

The size of union { char c[10]; int i; } (4-byte int, 4-byte alignment) is:

  • (A) 14
  • (B) 4
  • (C) 10
  • (D) 12

Q4MCQ1 markArrow

If p points to a struct with member x, which equals p->x?

  • (A) *p.x
  • (B) *(p.x)
  • (C) &p.x
  • (D) (*p).x

Q5MSQ1 markStructures

Which are allowed in C?

  • (A) Comparing two structs with ==
  • (B) A struct containing a member of its own type
  • (C) A struct containing a pointer to its own type
  • (D) Assigning one struct variable to another of the same type

11 · Rule Card

  • struct T { members }; access s.m or p->m ≡ (*p).m.
  • Struct assignment and argument passing copy all members.
  • typedef gives a type a new name.
  • Self-referential: struct T { …; struct T *next; } (pointer only).
  • Padding: member at multiple of its size; total multiple of largest member.
  • union: members overlap; size = largest member rounded for alignment.

12 · Concept Ledger

Unlocked in this lesson. From here on, these terms may be used.

structuremember. and -> operatorsstruct assignment (copy)typedefself-referential structurepaddingalignmentunion

13 · Answer Vault

Answer Vault

Try the questions first. Open when you are ready to check.

Recall Warm-up

  • 5 (four characters and '\0').
  • The array decays to a pointer to its first element, so the function works on the caller’s elements.
  • A stack frame: parameters, locals, return address.

Self-Test

Q1 Answer: (C)2 marks

b is a separate copy made before a.marks changed.

Output

7 A 95.0 | 8 92.5
  • (A) is wrong: p points to a, so a.marks changes.
  • (B) is wrong: Only b.roll was set to 8.
  • (D) is wrong: b was copied before the change.

Re-read: Lesson 1.6 — Structures, unions, typedef; self-referential structures; structure size and padding

Q2 Answer: 242 marks

a 0; b 4–7; c 8; d 16–23; total 24.

Re-read: Lesson 1.6 — Structures, unions, typedef; self-referential structures; structure size and padding

Q3 Answer: (D)1 mark

Largest member 10, rounded up to a multiple of 4: 12.

  • (A) is wrong: Union members overlap; sizes do not add.
  • (B) is wrong: The array needs 10 bytes.
  • (C) is wrong: Must be a multiple of 4.

Re-read: Lesson 1.6 — Structures, unions, typedef; self-referential structures; structure size and padding

Q4 Answer: (D)1 mark

The arrow dereferences first, then selects.

  • (A) is wrong: That parses as *(p.x).
  • (B) is wrong: p is a pointer; p.x is invalid.
  • (C) is wrong: That is an address.

Re-read: Lesson 1.6 — Structures, unions, typedef; self-referential structures; structure size and padding

Q5 Answer: (C) (D)1 mark

No == for structs; no infinite self-containment.

  • (A) is wrong: Compare members individually.
  • (B) is wrong: It would have infinite size.

Re-read: Lesson 1.6 — Structures, unions, typedef; self-referential structures; structure size and padding

Ready for the next idea?

Mark this item complete when you’ve finished reading and working through it.