Dr. Roger Ianjamasimanana

Correct use of structures in C

By Dr. Roger Ianjamasimanana

Structures in C are a powerful feature that allows programmers to group variables of different types under a single name. This capability is essential for modeling complex data entities and enhances the organization and readability of code. This comprehensive guide will walk you through the correct use of structures in C, including commented examples to illustrate each concept.

1. Introduction to structures in C

A structure in C is a user-defined data type that enables the combination of data items of different kinds. Structures are particularly useful for representing objects with multiple attributes, such as a student with a name, age, and grade.

2. Defining a structure

To define a structure, use the struct keyword followed by the structure name and its members enclosed in curly braces.


// Definition of a structure named 'Person'
struct Person {
    char name[50];
    int age;
    float height;
};
    

3. Declaring C structure variables

After defining a structure, you can declare variables of that structure type.


// Declaring a single structure variable
struct Person person1;

// Declaring multiple structure variables
struct Person person2, person3;
    

4. Initializing structures

Structures can be initialized at the time of declaration using an initializer list.


// Initializing a structure variable
struct Person person1 = {"Alice", 30, 5.5f};
    

5. Accessing structure members

Members of a structure can be accessed using the dot (.) operator.

 // Accessing and modifying structure members
#include <stdio.h>

// Define the struct Person
struct Person {
    char name[50];    // Assuming a maximum name length of 49 characters
    int age;
    float height;
};

int main() {
    // Initialize person1 with name, age, and height
    struct Person person1 = {"Alice", 30, 5.5f};
    
    // Accessing members
    printf("Name: %s\n", person1.name);
    printf("Age: %d\n", person1.age);
    printf("Height: %.1f\n", person1.height);
    
    // Modifying members
    person1.age = 31;
    person1.height = 5.6f;
    
    printf("Updated Age: %d\n", person1.age);
    printf("Updated Height: %.1f\n", person1.height);
    
    return 0;
}
    

6. Nested structures

The following C program demonstrates the use of nested structures. It defines two structures, Address and Person, where Person includes an Address structure as one of its members. The main function initializes a Person instance and prints out specific information.

 // Definition of the Address structure
#include <stdio.h>

struct Address {
    char street[100];
    char city[50];
    int zipcode;
};

// Definition of the Person structure, which includes Address as a nested structure
struct Person {
    char name[50];
    int age;
    struct Address address; // Nested structure
};

int main() {
    // Initializing a Person instance with nested Address
    struct Person person1 = {"Bob", 25, {"123 Main St", "Springfield", 12345}};
    
    // Printing the name and city of the person
    printf("Name: %s\n", person1.name);
    printf("City: %s\n", person1.address.city);
    
    return 0;
}
    

The above program begins by defining two structures: Address and Person.

  • Address: this holds information related to an address, including the street, city, and zipcode.
  • Person: this represents a person with a name, age, and an embedded Address structure.

A nested structure occurs when one structure is declared within another. In this example, the Person structure contains an Address structure as a member. This allows each Person instance to have its own unique address information encapsulated within the person data.

struct Person {
char name[50];
int age;
struct Address address; // Nested structure
};
    

In the main function, a Person instance named person1 is initialized with specific values, including the nested Address data.

struct Person person1 = {"Bob", 25, {"123 Main St", "Springfield", 12345}};
    

Here, the address member is initialized with an inline Address structure containing the street, city, and zipcode.

The program demonstrates how to access members of the structures by using the dot (.) operator. For nested structures, multiple dots are used to traverse the hierarchy.

printf("Name: %s\n", person1.name);
printf("City: %s\n", person1.address.city);
    
  • person1.name accesses the name member of the Person structure.
  • person1.address.city accesses the city member within the nested Address structure.

Expected output:

Name: Bob
City: Springfield
    

7. Pointers to structures

Pointers can be used to reference structure variables, allowing dynamic memory management and efficient data manipulation.

// Using pointers to structures
#include <stdio.h>

struct Person {
    char name[50];
    int age;
};

int main() {
    struct Person person1 = {"Charlie", 28};
    struct Person *ptr = &person1;
    
    // Accessing members using pointer
    printf("Name: %s\n", ptr->name); // Using arrow operator
    printf("Age: %d\n", ptr->age);
    
    return 0;
}
    

8. Passing structures to functions

Structures can be passed to functions either by value or by reference (using pointers), enabling modular and reusable code.

// Passing structures by value and by reference
#include <stdio.h>

// Structure definition
struct Person {
    char name[50];
    int age;
};

// Function that takes a structure by value
void displayPerson(struct Person p) {
    printf("Name: %s, Age: %d\n", p.name, p.age);
}

// Function that takes a structure by reference
void updateAge(struct Person *p, int newAge) {
    p->age = newAge;
}

int main() {
    struct Person person1 = {"Diana", 22};
    
    // Passing by value
    displayPerson(person1);
    
    // Passing by reference
    updateAge(&person1, 23);
    displayPerson(person1);
    
    return 0;
}
    

9. Arrays of structures

Arrays can store multiple structure variables, allowing batch processing of related data.

// Creating and using an array of structures
#include <stdio.h>

struct Person {
    char name[50];
    int age;
};

int main() {
    struct Person people[3] = {
        {"Eve", 29},
        {"Frank", 35},
        {"Grace", 27}
    };
    
    for(int i = 0; i < 3; i++) {
        printf("Person %d: %s, Age: %d\n", i+1, people[i].name, people[i].age);
    }
    
    return 0;
}
    

The code above defines a Person structure, initializes an array of three Person instances, and iterates through the array to print each person's details. Person holds information about a person, specifically their name and age. An array named people of type struct Person is declared and initialized with three elements. Each element represents a different person with a name and age. A for loop is used to iterate through the people array, accessing and printing each person's details.

Output:

Person 1: Eve, Age: 29
Person 2: Frank, Age: 35
Person 3: Grace, Age: 27

10. Best practices for a correct use of C structures

✍️
Use meaningful names

Choose descriptive names for structures and their members to enhance code readability.

✍️
Initialize structures

Always initialize structure variables to prevent undefined behavior due to uninitialized members.

✍️
Consistent formatting

Maintain a consistent code style for defining and using structures for better maintainability.

✍️
Use typedef for simplification

Use typedef to create aliases for structures, reducing the need to repeatedly use the struct keyword.

✍️
Encapsulate data

Keep structure members related and avoid unnecessary exposure of internal data to maintain modularity.

The use of typedef avoids using struct keyword every time a variable is declared. See the table below for illustration

Using typedef vs. traditional structure declarations
Aspect With typedef syntax Without typedef
Structure definition
typedef struct {
char name[50];
int age;
float height;
} Person;
struct Person {
char name[50];
int age;
float height;
};
Person person1;
struct Person person1;
Code brevity More concise and cleaner code. Requires the struct keyword every time a variable is declared.
// Example of using typedef with structures for simplification
#include <stdio.h>

// Typedef for the Person structure
typedef struct {
    char name[50];
    int age;
    float height;
} Person;

int main() {
    Person person1 = {"Henry", 40, 6.1f};
    
    printf("Name: %s\n", person1.name);
    printf("Age: %d\n", person1.age);
    printf("Height: %.1f\n", person1.height);
    
    return 0;
}
    

11. Summary

Structures in C are indispensable for managing and organizing complex data. By allowing the grouping of different data types under a single name, they facilitate the modeling of real-world entities and enhance code clarity. Understanding how to define, initialize, access, and manipulate structures, along with adhering to best practices, is crucial for writing efficient and maintainable C programs. Correct use of structures allow programmers to handle complex data with ease and precision.

feature-top
Readers’ comment
feature-top
Log in to add a comment
🔐 Access