CSC115 C Programming

C ProgrammingUnit 88 min read

Unit 8: Structures, Nested Structures & Unions – Key Concepts

Unit 8 of C Programming: introduces structures and unions, their syntax, memory layout, initialization, nested structures, pointers, typedefs, and practical applications such as student records and book catalogs.

Key points

  • A structure groups heterogeneous data into a single composite type.
  • Nested structures allow hierarchical data modeling and are accessed with the dot operator.
  • A union shares memory among its members, saving space when only one member is used at a time.
  • `typedef` simplifies complex type names and improves code readability.
  • Understanding memory layout of structs and unions is essential for efficient data handling and debugging.

1. Introduction to Structures

A structure (struct) is a user‑defined composite data type that groups variables of different types under a single name.

struct Student {
    int    sid;
    char   name[50];
    char   address[100];
    float  cgpa;
};
  • Member variables can be of any type: primitive, arrays, pointers, or even other structures.
  • The structure itself is a type; variables of that type are called structure objects.

1.1 Syntax & Declaration

struct tag_name { /* member declarations */ };  // tag_name is optional
  • Tag: optional identifier used to refer to the structure type later.
  • Anonymous struct: no tag; must be used immediately or with typedef.

1.2 Memory Layout

+-----------------+-----------------+-----------------+-----------------+
|      sid        |      name[50]   |    address[100] |      cgpa       |
+-----------------+-----------------+-----------------+-----------------+
  • Each member occupies its natural alignment; the compiler may insert padding for alignment.
  • Size of struct = sum of member sizes + padding.

1.3 Initialization

struct Student s1 = { 101, "Ram", "KTM", 3.75 };
  • Designated initializers (C99) allow specifying members by name:
    struct Student s2 = { .sid = 102, .name = "Sita", .cgpa = 3.90 };
    
  • Uninitialized members receive zero (for static storage) or indeterminate values (for automatic storage).

1.4 Accessing Members

  • Dot operator (.) for objects: s1.cgpa.
  • Arrow operator (->) for pointers:
    struct Student *p = &s1;
    printf("%f", p->cgpa);
    

2. Nested Structures

A structure can contain another structure as a member, enabling hierarchical data representation.

struct Address {
    char city[30];
    char country[30];
};

struct Student {
    int          sid;
    char         name[50];
    struct Address addr;
    float        cgpa;
};

2.1 Accessing Nested Members

printf("%s, %s", s1.addr.city, s1.addr.country);

2.2 Example: Fibonacci Prime Check

Problem: Determine whether the nth Fibonacci number is prime.
Solution: Use nested structures to store Fibonacci term and its primality flag.

#include <stdio.h>
#include <stdbool.h>

struct FibInfo {
    unsigned long long term;
    bool isPrime;
};

bool isPrime(unsigned long long n) {
    if (n < 2) return false;
    for (unsigned long long i = 2; i * i <= n; ++i)
        if (n % i == 0) return false;
    return true;
}

int main(void) {
    int n;
    printf("Enter n: ");
    scanf("%d", &n);

    struct FibInfo fib = {0, false};
    unsigned long long a = 0, b = 1;
    for (int i = 1; i <= n; ++i) {
        fib.term = b;
        a = b;
        b = a + b;
    }
    fib.isPrime = isPrime(fib.term);

    printf("Fib(%d) = %llu is %sprime.\n",
           n, fib.term, fib.isPrime ? "" : "not ");
    return 0;
}

Trace for n = 7

i a b fib.term isPrime
1 0 1 1 false
2 1 1 1 false
3 1 2 2 true
4 2 3 3 true
5 3 5 5 true
6 5 8 8 false
7 8 13 13 true

Result: Fib(7) = 13 is prime.

3. Unions

A union is a special data type where all members share the same memory location. Only one member can hold a value at a time.

union Data {
    int    i;
    float  f;
    char   str[20];
};

3.1 Memory Layout

+-----------------+
|  i / f / str[20]|
+-----------------+
  • Size of union = size of its largest member (plus padding).

3.2 Advantages

  • Memory efficiency: useful when a variable can hold one of several types.
  • Variant data representation: e.g., a packet header that can be interpreted differently.

3.3 Disadvantages

  • No type safety: programmer must remember which member is active.
  • Limited to one active member: storing multiple values simultaneously is impossible.

3.4 Example: Variant Data

#include <stdio.h>

union Value {
    int   i;
    float f;
    char  c;
};

int main(void) {
    union Value v;
    v.i = 42;
    printf("int: %d\n", v.i);

    v.f = 3.14f;          // overwrites previous int
    printf("float: %f\n", v.f);

    v.c = 'A';
    printf("char: %c\n", v.c);
    return 0;
}

4. Struct vs Array vs Union

Feature Structure Array Union
Members Heterogeneous Homogeneous Heterogeneous
Memory Sum of members + padding N * size of element Size of largest member
Access . or -> [] . or ->
Use case Record of related data Sequence of same type Variant data sharing memory
Size Fixed (depends on members) Fixed (depends on N) Fixed (size of largest member)

4.1 Struct vs Array

  • Struct groups different data types; Array stores same type.
  • Example: struct Point { int x; int y; }; vs int arr[2];

4.2 Struct vs Union

  • Struct allocates separate memory for each member.
  • Union shares memory; only one member is valid at a time.

5. Typedef and Aliases

typedef creates an alias for a type, simplifying complex declarations.

typedef struct {
    int    sid;
    char   name[50];
    char   address[100];
    float  cgpa;
} Student;

Now we can declare:

Student s1, s2;

5.1 Typedef for Unions

typedef union {
    int    i;
    float  f;
    char   str[20];
} Data;

6. Pointers to Structures

Pointers to structures are essential for dynamic memory allocation and linked data structures.

Student *p = malloc(sizeof(Student));
p->sid = 103;

6.1 Array of Pointers to Structs

Student *students[10];
for (int i = 0; i < 10; ++i)
    students[i] = malloc(sizeof(Student));

7. Practical Applications

Application Structure/Union Used Why
Student database struct Student Stores heterogeneous student data.
Book catalog struct Book Each book has title, author, price.
Graphics vertex struct Vertex { float x, y, z; } Group coordinates.
Network packet union Packet { Header h; Data d; } Variant packet types.
Embedded systems union { uint8_t b; struct { uint4_t a:4; uint4_t b:4; } bits; } Bit‑field manipulation.

7.1 Example: Book Catalog

typedef struct {
    char title[100];
    char author[50];
    float price;
} Book;

int main(void) {
    Book books[50];
    for (int i = 0; i < 50; ++i) {
        printf("Enter details for book %d:\n", i+1);
        scanf("%99s %49s %f", books[i].title, books[i].author, &books[i].price);
    }
    // Display books priced above 500
    printf("\nBooks priced above 500:\n");
    for (int i = 0; i < 50; ++i)
        if (books[i].price > 500)
            printf("%s by %s, Price: %.2f\n", books[i].title, books[i].author, books[i].price);
    return 0;
}

8. Common Mistakes & Debugging Tips

Mistake Explanation Fix
Using . instead of -> on a pointer Compile error or wrong access Use -> for pointers
Forgetting to allocate memory for struct pointer Segmentation fault malloc or calloc before use
Overlooking padding in struct Miscalculating size Use sizeof and offsetof
Accessing inactive union member Undefined behavior Keep track of active member or use a tag field

9. Summary

  • Structures group related data; memory layout is contiguous.
  • Nested structures enable hierarchical modeling.
  • Unions share memory; useful for variant data.
  • Typedef improves readability.
  • Pointers to structs are essential for dynamic data structures.
  • Understanding memory layout aids in efficient coding and debugging.

Exam tip

  1. Code Writing

    • Expect to write complete programs: define structs/unions, initialize, input/output, and conditional logic.
    • Practice initializing with designated initializers and using typedef.
  2. Conceptual Questions

    • Be ready to explain memory layout, padding, and differences between struct and union.
    • Compare struct vs array vs union in a table.
  3. Trace & Debug

    • Given a small program, trace the values of struct members or union fields.
    • Identify which member is active in a union after assignments.
  4. Practical Scenarios

    • Design a struct for a real‑world entity (e.g., student, book, employee).
    • Use nested structs to model addresses or dates.
  5. Time Management

    • Allocate 30 % of the exam time to coding, 30 % to conceptual questions, 40 % to tracing/debugging.

Focus on clarity, correct syntax, and logical flow. Good luck!

Based on the TU BSc CSIT syllabus for C Programming (CSC115), unit 8.

Discussion

Loading…