Introduction to C Language Structures: A Comprehensive Guide

Introduction to C Language Structures: A Comprehensive Guide

1. Basic Concepts of Structures

1. Structure Definition

// Basic structure definition
struct Student {
    int id;                // Student ID
    char name[50];         // Name
    char gender;           // Gender
    int age;              // Age
    float score;          // Score
};

// Structure definition with typedef
typedef struct {
    int x;
    int y;
} Point;

2. Structure Variable Declaration

// Method 1: Declare after defining
struct Student s1;

// Method 2: Define and declare simultaneously
struct Student s2 = {1001, "Zhang San", 'M', 20, 85.5};

// Method 3: Declaration using typedef
Point p1 = {10, 20};

// Method 4: Partial member initialization
struct Student s3 = {.id = 1002, .name = "Li Si"};

2. Accessing Structure Members

1. Direct Member Access

struct Student s1;

// Assigning values to members
s1.id = 1001;
strcpy(s1.name, "Zhang San");
s1.gender = 'M';
s1.age = 20;
s1.score = 85.5;

// Accessing members
printf("Student ID: %d\n", s1.id);
printf("Name: %s\n", s1.name);
printf("Score: %.1f\n", s1.score);

2. Pointer Access to Members

struct Student *ps = &s1

// Using arrow operator
ps->id = 1002;
strcpy(ps->name, "Li Si");
ps->score = 90.5;

// Or using dereferencing
(*ps).age = 21;
(*ps).gender = 'F';

3. Structure Arrays

1. Defining and Initializing Structure Arrays

// Defining a structure array
struct Student class[3] = {
    {1001, "Zhang San", 'M', 20, 85.5},
    {1002, "Li Si", 'F', 19, 92.0},
    {1003, "Wang Wu", 'M', 21, 78.5}
};

// Dynamically allocating structure array
struct Student *students = (struct Student*)malloc(3 * sizeof(struct Student));

2. Accessing Structure Arrays

// Traversing the structure array
for (int i = 0; i < 3; i++) {
    printf("Student ID: %d, Name: %s, Score: %.1f\n",
           class[i].id,
           class[i].name,
           class[i].score);
}

// Accessing using pointers
for (int i = 0; i < 3; i++) {
    printf("Student ID: %d, Name: %s\n",
           (students + i)->id,
           (students + i)->name);
}

4. Structure Functions

1. Structure as Function Parameters

// Pass by value
void printStudent(struct Student s) {
    printf("Student ID: %d\n", s.id);
    printf("Name: %s\n", s.name);
    printf("Score: %.1f\n", s.score);
}

// Pointer passing (recommended)
void updateScore(struct Student *ps, float newScore) {
    ps->score = newScore;
}

// Function calls
struct Student s1 = {1001, "Zhang San", 'M', 20, 85.5};
printStudent(s1);
updateScore(&s1, 90.0);

2. Structure as Function Return Value

// Returning a structure
struct Student createStudent(int id, const char *name, float score) {
    struct Student s;
    s.id = id;
    strcpy(s.name, name);
    s.score = score;
    return s;
}

// Returning a structure pointer
struct Student* createStudentPtr(int id, const char *name, float score) {
    struct Student *ps = (struct Student*)malloc(sizeof(struct Student));
    ps->id = id;
    strcpy(ps->name, name);
    ps->score = score;
    return ps;
}

5. Nested Structures

1. Defining Nested Structures

// Defining an address structure
struct Address {
    char street[100];
    char city[50];
    char state[50];
    char zipcode[10];
};

// Defining a student structure that includes an address
struct StudentInfo {
    int id;
    char name[50];
    struct Address addr;    // Nested structure
    float score;
};

2. Accessing Nested Structures

// Initializing nested structure
struct StudentInfo student = {
    1001,
    "Zhang San",
    {"Zhongshan Road", "Beijing", "Beijing", "100000"},
    85.5
};

// Accessing nested structure members
printf("Name: %s\n", student.name);
printf("City: %s\n", student.addr.city);

// Accessing using pointers
struct StudentInfo *ps = &student
printf("Street: %s\n", ps->addr.street);

6. Bit-field Structures

// Bit-field structure definition
struct Flags {
    unsigned int is_active : 1;    // 1 bit
    unsigned int is_valid : 1;     // 1 bit
    unsigned int mode : 2;         // 2 bits
    unsigned int priority : 3;     // 3 bits
};

// Using bit-fields
struct Flags flags;
flags.is_active = 1;
flags.mode = 2;
flags.priority = 5;

7. Practical Application Example

1. Student Information Management System

// Defining student structure
typedef struct {
    int id;
    char name[50];
    float scores[3];  // Scores for three subjects
    float average;    // Average score
} Student;

// Calculating average score
void calculateAverage(Student *s) {
    float sum = 0;
    for (int i = 0; i < 3; i++) {
        sum += s->scores[i];
    }
    s->average = sum / 3;
}

// Printing student information
void printStudent(const Student *s) {
    printf("Student ID: %d\n", s->id);
    printf("Name: %s\n", s->name);
    printf("Average Score: %.2f\n", s->average);
}

// Example usage
int main() {
    Student students[3] = {
        {1001, "Zhang San", {85, 90, 88}},
        {1002, "Li Si", {92, 89, 90}},
        {1003, "Wang Wu", {78, 85, 82}}
    };
    
    // Processing student information
    for (int i = 0; i < 3; i++) {
        calculateAverage(&students[i]);
        printStudent(&students[i]);
    }
    
    return 0;
}

Notes:

  1. Memory alignment of structures
  2. Using structure pointers
  3. Dynamic memory management
  4. String handling
  5. Member access methods

Best Practices:

  1. Use typedef to simplify definitions
  2. Choose appropriate member types
  3. Be mindful of structure size
  4. Organize structure members effectively
  5. Use pointer passing to improve efficiency

Friends, this is the basic content of C language structures! Practice more and use them flexibly. Feel free to ask questions in the comments!

Leave a Comment