Detailed Explanation of Structures in C Language

In the C language, we have learned about basic data types such as char, short, int, long, etc., and we have also learned how to construct collections of data using arrays. However, in different situations, we often need to combine different data types to form a new data structure.For example, when writing a student information management program, we need to store student information, which includes the student’s name, student ID, gender, age, and other data. Student information consists of different types of data, and describing a student’s information requires defining (declaring) multiple variables of different data types, as well as an array to describe the information of multiple students.

Definition of Structures

The C language provides a way to define custom data types to describe structured data like student information. The syntax for defining a structure is as follows:

struct StructureName { TypeName1 memberName1; TypeName2 memberName2; ... TypeNameN memberNameN; };

Here, struct is the keyword for defining a structure, and StructureName is the name of the structure, which must be a valid C identifier. The body of the structure is enclosed in a pair of curly braces, within which multiple structure members can be defined, with each member defined in the same way as variable declarations, separated by semicolons.For example: the student information structure.

struct STUDENT { // Student Name char name[30]; // Age int age; };

The above defines a structure named STUDENT, and it is common to use all uppercase letters for structure names to distinguish them from variable names. The structure has two members: name and age.The defined structure is just a custom data type, and its usage is the same as other data types; a structure variable must be defined in the program.For example, the following defines a structure variable student of the STUDENT structure, where STUDENT is the structure and student is the structure variable.struct STUDENT student;It is also possible to define a structure variable directly when defining the structure.

struct STUDENT { // Student Name char name[30]; // Age int age; } student;

To access the members of a structure, C provides the member access operator “.”. The member access operator is a “.” symbol between the structure variable name and the member to be accessed. Example 8-1 demonstrates how to access structure members.Example [1] Using Structures PracticeProgram Listing sample.c

#include <stdio.h>#include <string.h>// Define student information structure struct STUDENT { // Student Name char name[30]; // Age int age; } student; // Main function void main() { // Initialize structure variable student // Access structure members using “.” operator student.age = 21; strcpy(student.name, "Ma Han"); // Output structure variable student printf("Name: %s\nAge: %d\n", student.name, student.age); }

Example 8-1 defines the STUDENT structure and declares the structure variable student. In the main() function, the structure variable student is initialized, and the member information of the structure variable is output.

Structure Arrays

The elements of an array can also be of structure type, so a structure array can be declared, where each element of the structure array is a variable of the same structure type. In practical applications, structure arrays are often used to represent collections of data with the same data structure. For example: student information in a learning information management program, book information in a library management system, etc.The syntax for declaring a structure array variable is the same as that for declaring other data type arrays. When declaring a structure array variable, the length of the array is generally specified, and then the elements of the array are assigned values in the program.For example, a structure array containing 10 students can be created:struct STUDENT students[10];This students array contains 10 STUDENT structures, and you can access or modify the structure elements in the array using array indexing.You can access and modify the members of these structures using array indexing. The following code sets the name and age of the first student:

students[0].age = 20; students[0].name = "Zhang San";

Example [2] Traversing Structure Array Elements

Program Listing #include <stdio.h>#include <string.h>// Define student structure typedef struct { char name[50]; int age; float score; } Student; int main() { int i; // Initialize student array struct STUDENT students[3] = { {"Zhang San", 20}, {"Li Si", 21}, {"Wang Wu", 19} }; // Traverse student array and print information printf("Student Information:\n"); for(i = 0; i < 3; i++) { printf("Name: %s, Age: %d", students[i].name, students[i].age); } return 0; }

The example code defines a structure named STUDENT, which contains the student’s name (a character array) and age (an integer). Then, in the main function, a STUDENT structure array containing 3 students is created and initialized with each student’s information. A for loop is used to traverse this array and print each student’s name and age using the printf function.

Structure Pointers

A structure pointer is a pointer that points to a structure variable, and through the structure pointer, the data members of the structure can be accessed and modified indirectly.The basic syntax for defining a structure pointer is as follows:struct StructureName *pointerName;For example, for the previously defined STUDENT structure, a pointer to a STUDENT structure variable can be defined as follows:struct STUDENT *studentPtr;The above-defined structure pointer variable studentPtr points to a random memory address, and it needs to be initialized before it can be used. The initialization code is as follows:

struct STUDENT *studentPtr; struct STUDENT student = {"Tom", 20}; studentPtr = &student; printf("Name: %s\nAge: %d\n", studentPtr->name, studentPtr->age);

The above initialization code first defines a STUDENT structure variable student, and then assigns the memory address of student to the structure pointer variable studentPtr.There is another way to initialize a structure pointer variable, which is to allocate memory directly for the structure pointer variable using dynamic memory allocation, which will be used in the “Memory Management” chapter. Example [8-3] uses this method.Example [3] Structure Pointer Application Example

Program Listing #include <stdio.h>#include <stdlib.h>#include <string.h>// Define student structure typedef struct { char name[50]; int age; float score; } Student; // Create student Student* createStudent(const char* name, int age, float score) { Student* student = (Student*)malloc(sizeof(Student)); if (student == NULL) { printf("Memory allocation failed!\n"); exit(1); } strcpy(student->name, name); student->age = age; student->score = score; return student; } // Print student information void printStudent(Student* student) { printf("Name: %s, Age: %d, Score: %.2f\n", student->name, student->age, student->score); } // Free student memory void freeStudent(Student* student) { if (student != NULL) { free(student); student = NULL; } } int main() { // Create student structure pointers Student* student1 = createStudent("Zhang San", 20, 85.5); Student* student2 = createStudent("Li Si", 21, 92.0); // Print student information printStudent(student1); printStudent(student2); // Free student memory freeStudent(student1); freeStudent(student2); return 0; }

The example code defines three functions:createStudent: This function takes the student’s name, age, and score as parameters and dynamically allocates memory to create a new student structure. It then sets the fields of the structure and returns a pointer to that structure.printStudent: This function takes a pointer to a student structure as a parameter and prints the student’s information.freeStudent: This function takes a pointer to a student structure as a parameter and frees the memory occupied by that structure.In the main function, two student structure pointers student1 and student2 are created, and the createStudent function is used to dynamically create two student objects. The printStudent function is then called to print the information of these two students. Finally, the freeStudent function is called to free the memory occupied by these two student objects.Example [3] demonstrates how to use structure pointers to dynamically manage the creation and destruction of student objects. In practical applications, this method can handle large amounts of data more flexibly and can dynamically allocate and free memory as needed.

Structures as Function Parameters

When a structure is passed as a function parameter, what is actually passed is a copy of the structure, which means that any modifications to the structure within the function will not affect the original structure. If modifications to the original structure are needed, a pointer to the structure can be passed.There are two ways to pass structures as function parameters: by value and by pointer.Pass by value: In this case, the function receives a copy of the structure. Therefore, modifications to the structure within the function will not affect the original structure.Pass by pointer: In this case, the function receives a pointer to the structure. Therefore, modifications to the structure within the function will directly affect the original structure.Example [4] Structure as Value Passing

#include <stdio.h> typedef struct { int id; char name[50]; } Student; void printStudent(Student s) { printf("ID: %d, Name: %s\n", s.id, s.name); } int main() { Student stu = {1, "Alice"}; printStudent(stu); return 0; } typedef struct { int id; char name[50]; } Student; void printStudent(Student s) { printf("ID: %d, Name: %s\n", s.id, s.name); } int main() { Student stu = {1, "Alice"}; printStudent(stu); return 0; }

When the structure is large, passing by value may result in a large amount of data being copied, which can affect performance.Example [5] Structure as Pointer Passing

#include <stdio.h>#include <string.h> typedef struct { int id; char name[50]; } Student; void updateStudent(Student *s) { s->id = 2; strcpy(s->name, "Bob"); } int main() { Student stu = {1, "Alice"}; printf("Before update: ID: %d, Name: %s\n", stu.id, stu.name); updateStudent(&stu); printf("After update: ID: %d, Name: %s\n", stu.id, stu.name); return 0; }

Passing by pointer is more efficient because it only passes an address rather than the entire structure. However, it also introduces additional risks, as the function can modify the original structure.

Leave a Comment