# Structures, Unions, Enums and typedef in C

Source: https://skills101.in/learn/c-programming/c-structures-and-unions — Skills101 free tutorial (C Programming). Updated 2026-11-09.

A **structure** groups different types of data under one name — like a student record with a name, roll number and marks.

## 1. Defining and using a struct

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

struct Student {
    int roll;
    char name[20];
    float cgpa;
};

int main(void) {
    struct Student s1 = {101, "Asha", 8.9f};
    struct Student s2;
    s2.roll = 102;
    strcpy(s2.name, "Ravi");
    s2.cgpa = 7.4f;
    printf("%d %s %.1f\n", s1.roll, s1.name, s1.cgpa);
    printf("%d %s %.1f\n", s2.roll, s2.name, s2.cgpa);
    return 0;
}
```

```text
101 Asha 8.9
102 Ravi 7.4
```

Members are accessed with the **dot operator** `.`.

## 2. typedef: a shorter name

```c
typedef struct {
    int x, y;
} Point;          /* now write Point instead of struct ... */
```

## 3. Arrays of structures and pointers (->)

```c
#include <stdio.h>

typedef struct {
    char name[20];
    int marks;
} Student;

void bonus(Student *s) {          /* pointer: changes the original */
    s->marks += 5;                /* s->marks is (*s).marks */
}

int main(void) {
    Student cls[3] = {{"Asha", 88}, {"Ravi", 71}, {"Neha", 93}};
    bonus(&cls[1]);
    int top = 0;
    for (int i = 1; i < 3; i++)
        if (cls[i].marks > cls[top].marks) top = i;
    printf("%s %d | topper %s\n", cls[1].name, cls[1].marks, cls[top].name);
    return 0;
}
```

```text
Ravi 76 | topper Neha
```

Use **`->`** when you have a **pointer** to a structure. Passing a pointer also avoids copying a big structure.

## 4. Structure padding and union

![struct with char, int and double takes 16 bytes because padding aligns int and double; a union of the same members takes 8 bytes because all members share the same memory](https://skills101.in/learn-img/c-programming/struct-union.svg)

```c
#include <stdio.h>

struct S { char c; int n; double d; };
union U  { char c; int n; double d; };

int main(void) {
    printf("struct=%zu union=%zu\n", sizeof(struct S), sizeof(union U));
    union U u;
    u.n = 65;
    printf("%c\n", u.c);      /* the same bytes read as a char */
    return 0;
}
```

```text
struct=16 union=8
A
```

- A **struct** stores **all** members, one after another, plus **padding** so each member starts at an address the CPU likes (alignment). Ordering members from largest to smallest often reduces padding.
- A **union** stores all members in the **same memory**; its size is the largest member. Only the last-written member is meaningful. (Reading `u.c` after writing `u.n = 65` shows 'A' on little-endian machines — a classic trick question.)

| | struct | union |
|---|---|---|
| Memory | sum of members + padding | largest member |
| Members valid at once | all | one |
| Use | records | saving memory, viewing bytes in different ways |

## 5. enum: named constants

```c
#include <stdio.h>

enum Day { MON = 1, TUE, WED, THU, FRI, SAT, SUN };

int main(void) {
    enum Day today = WED;
    printf("%d %d\n", today, SUN);
    printf("%s\n", today >= SAT ? "weekend" : "weekday");
    return 0;
}
```

```text
3 7
weekday
```

Values continue from the previous one (MON = 1 → TUE = 2 …). If you don't set any, the first is 0.

## 6. Nested structures

```c
typedef struct { int day, month, year; } Date;
typedef struct { char name[20]; Date dob; } Person;
/* access: person.dob.year */
```

## Common mistakes

- Using `.` on a pointer (use `->`) or `->` on a normal variable.
- Assuming sizeof(struct) = the sum of member sizes (padding!).
- Reading a union member other than the one you last wrote.

## Quick recap

- struct groups different types; access with `.` or `->` (pointers).
- typedef gives a short name.
- struct = all members + padding; union = shared memory, size of the largest.
- enum gives readable names to integer constants.


Practice quiz and free certificate: https://skills101.in/learn/c-programming/c-structures-and-unions