ITM102 Structured Programming in C

Structured Programming in CUnit 711 min read

Structures & Unions: Data Packaging & Memory Efficiency

Unit 7 of Structured Programming in C covers structures (grouping related data) and unions (memory-efficient alternatives), their syntax, differences, and real-world applications in databases, financial records, and network packets. Learn how to define, access, and use them with pointers, and compare their memory usage

TAKEAWAYS:

  • Structures bundle heterogeneous data (e.g., student with name, roll, marks) under one name, accessed via . or ->.
  • Unions share memory for multiple variables (e.g., employee storing either salary or hourly_wage), saving space but risking data corruption.
  • Key differences: structures allocate memory for all members; unions allocate memory for the largest member only.
  • Pointers to structures (struct *ptr) enable dynamic memory allocation and linked data (e.g., student records in a class).
  • Real-world uses: eSewa (transaction records), Ncell (customer billing), NEPSE (stock portfolio tracking).
  • Always initialize unions carefully to avoid garbage values in unused members.

A structure (struct) groups variables of different types under a single name. It mimics real-world entities (e.g., a student has a name, roll, and marks).

Syntax & Definition

struct student {
    char name[50];
    int roll;
    float marks;
};
  • Members: Variables inside the structure (e.g., name, roll).
  • Declaration: struct student s1; creates an instance.
  • Access: Use . (dot operator) or -> (arrow operator for pointers).

Example: Student Record

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

struct student {
    char name[50];
    int roll;
    float marks;
};

int main() {
    struct student s1;
    strcpy(s1.name, "Ramesh");
    s1.roll = 101;
    s1.marks = 85.5;

    printf("Name: %s, Roll: %d, Marks: %.2f\n", s1.name, s1.roll, s1.marks);
    return 0;
}

Output:

Name: Ramesh, Roll: 101, Marks: 85.50

Memory Layout

[object Object]0
Memory layout of a `struct student` (58 bytes: 50 chars + 4 int + 4 float)
  • Total size: 50 (name) + 4 (roll) + 4 (marks) = 58 bytes (padding may add extra bytes for alignment).

Pointers to Structures

struct student *ptr = &s1;
printf("Roll: %d\n", ptr->roll);  // Equivalent to (*ptr).roll

Use case: Linked lists of student records in a class roster.

headstudent1student2student3NULL
Pointer to a `struct student` node in a linked list (showing `next` pointer)

2. Unions: Memory Efficiency at a Cost

A union shares memory for all members. Only one member holds a value at a time.

Syntax & Definition

union employee {
    int salary;
    float hourly_wage;
};
  • Memory: Allocates space for the largest member (e.g., float uses 4 bytes).
  • Access: Same as structures (union_name.member).

Example: Employee Payroll

union employee emp;
emp.salary = 50000;
printf("Salary: %d\n", emp.salary);  // Output: 50000

```figure
{"type":"array","values":[{"name":"emp1","fields":[{"name":"salary","value":"50000","type":"int","offset":0,"shared":true},{"name":"hourly_wage","value":"null","type":"float","offset":0,"shared":false}],"total_size":4},{"name":"emp2","fields":[{"name":"salary","value":"null","type":"int","offset":0,"shared":false},{"name":"hourly_wage","value":"250.5","type":"float","offset":0,"shared":true}],"total_size":4}],"caption":"Union memory usage: only one field active per instance (4 bytes each)"}

emp.hourly_wage = 250.5; printf("Hourly wage: %.2f\n", emp.hourly_wage); // Output: 250.50 Warning: After assigning hourly_wage, salary becomes undefined (garbage value).

Memory Layout

[object Object]0
Memory layout of a `union employee` (4 bytes: only one field occupies space at a time)
  • Total size: 4 bytes (size of float).

When to Use Unions

  • Network packets: Storing either an IP address or a port number.
  • Database records: Alternate fields (e.g., phone or email).
  • Hardware registers: Reading/writing different bits as integers or floats.

3. Key Differences: Structures vs. Unions

Feature Structure Union
Memory Allocation Sum of all members Size of the largest member
Data Access All members valid simultaneously Only one member valid at a time
Use Case Grouped data (e.g., student) Memory optimization (e.g., IP/port)
Initialization Safe (all members initialized) Risky (uninitialized members)
Example struct date { int day, month; } union data { int x; float y; }

4. Real-World Applications

In Nepal

  1. eSewa Transactions

    • Uses structures to store:
      struct transaction {
          char user_id[20];
          int amount;
          char status[10];  // "Success"/"Failed"
      };
      
    • Why? Bundles related data (user, amount, status) for processing.
  2. Ncell Billing System

    • Uses unions to store either:
      union payment {
          int prepaid_balance;
          float postpaid_bill;
      };
      
    • Why? Saves memory by reusing space for prepaid or postpaid data.
  3. NEPSE Stock Portfolio

    • Structures track:
      struct stock {
          char symbol[10];
          int quantity;
          float price;
      };
      
    • Example: A portfolio with 100 shares of NTC at ₹100/share and 50 shares of NMB at ₹500/share.

Global Examples

  1. WhatsApp Messages

    • Uses unions in its protocol buffer to store either:
      • A text message or
      • An image metadata (without duplicating memory).
    • How? Saves bandwidth by sharing memory for different message types.
  2. Google’s Protocol Buffers

    • Uses unions to define flexible message formats:
      message UserProfile {
          oneof kind {
              string email = 1;
              string phone = 2;
          }
      }
      
    • Why? Efficient serialization for APIs.
  3. Bank Loan Calculations

    • Structures store loan details:
      struct loan {
          char customer[50];
          float principal;
          float rate;
          int tenure;
      };
      
    • Example: Calculate monthly EMI for a ₹500,000 loan at 8% for 10 years:
      float emi = (loan.principal * loan.rate * (1 + loan.rate)^tenure) / ((1 + loan.rate)^tenure - 1);
      

5. Common Pitfalls & Best Practices

  1. Uninitialized Unions

    • Always initialize the member you’ll use:
      union data d;
      d.x = 10;  // Safe
      // printf("%d", d.y);  // Undefined behavior!
      
  2. Pointer Arithmetic

    • Structures: ptr++ moves by sizeof(struct).
    • Unions: ptr++ moves by sizeof(union).
  3. Nested Structures

    • Combine structures for complex data:
      struct address {
          char city[30];
          int pincode;
      };
      struct employee {
          char name[50];
          struct address addr;
      };
      
  4. Typedef for Simplicity

    • Avoid struct keyword repetition:
      typedef struct student {
          char name[50];
          int roll;
      } Student;
      Student s1;  // No 'struct' needed
      

6. Worked Example: Student Database

Task: Store 3 students and print their details using structures.

[object Object]0[object Object]1[object Object]2
Array of 3 `Student` structures in memory (174 bytes total: 3 × 58 bytes each)
#include <stdio.h>
#include <string.h>

typedef struct {
    char name[50];
    int roll;
    float marks;
} Student;

int main() {
    Student students[3];
    int i;

    // Input data
    for (i = 0; i < 3; i++) {
        printf("Enter name, roll, marks for student %d:\n", i+1);
        scanf("%s %d %f", students[i].name, &students[i].roll, &students[i].marks);
    }

    // Print data
    printf("\nStudent Records:\n");
    for (i = 0; i < 3; i++) {
        printf("Name: %s, Roll: %d, Marks: %.2f\n",
               students[i].name, students[i].roll, students[i].marks);
    }

    return 0;
}

Sample Input/Output:

Enter name, roll, marks for student 1:
Ramesh 101 85.5
Enter name, roll, marks for student 2:
Sita 102 90.0
Enter name, roll, marks for student 3:
Hari 103 78.5

Student Records:
Name: Ramesh, Roll: 101, Marks: 85.50
Name: Sita, Roll: 102, Marks: 90.00
Name: Hari, Roll: 103, Marks: 78.50

Trace Table:

Step students[0].name students[0].roll students[0].marks
1 "Ramesh" 101 85.5
2 "Sita" 102 90.0
3 "Hari" 103 78.5

7. Exam Tip: How to Score Full Marks

  1. Define Clearly

    • Always start with:
      struct name {
          type member1;
          type member2;
      };
      
  2. Compare Structures vs. Unions

    • Exam question: "List 3 differences between structures and unions."
    • Answer:
      • Memory allocation (sum vs. largest member).
      • Data validity (all vs. one member at a time).
      • Use case (grouped data vs. memory optimization).
  3. Show Memory Layouts

    • Draw diagrams for:
      • Structure size calculation.
      • Union memory sharing.
  4. Code Correctness

    • Use typedef to simplify syntax.
    • Initialize unions before access.
  5. Real-World Link

    • Relate to eSewa transactions, Ncell billing, or bank loans in explanations.

In the real world

  • eSewa Transaction Records: Uses struct to bundle user_id, amount, and status (success/failure) for each transaction. This ensures all related data is stored together for processing and auditing.
  • Ncell Prepaid/Postpaid Billing: Uses union to store either prepaid_balance (integer) or postpaid_bill (float) in the same memory space, optimizing storage for different billing types.
  • NEPSE Stock Portfolio Tracking: Uses nested struct (e.g., struct stock with symbol, quantity, and price) to manage diverse stock holdings in a single portfolio, enabling calculations like total value or profit/loss.

Based on the TU BITM syllabus for Structured Programming in C (ITM102), unit 7.

Discussion

Loading…