struct在C语言中的用法(非常详细,附带示例)
C语言中的结构体(struct)是一种用户自定义的复合数据类型,它允许我们将不同类型的数据项组合在一起,形成一个逻辑整体。
结构体的概念源于现实世界中的对象,这些对象通常具有多个属性。例如,一个学生可能有姓名、年龄、学号等属性;一本书可能有书名、作者、出版日期等属性。在程序设计中,我们经常需要处理这样的复合数据,而结构体正是为此而生的。
结构体的本质是一种将多个变量组合在一起的方式,这些变量可以是不同的数据类型。通过使用结构体,我们可以更好地组织和管理相关的数据,使代码更加清晰和易于理解。结构体不仅提高了代码的可读性,还增强了数据的封装性,这是面向对象编程思想的一种体现。
1. 结构体的定义
结构体定义的一般语法如下:
struct 结构体名 { 数据类型1 成员名1; 数据类型2 成员名2; ... };
定义结构体时,我们使用 struct 关键字,后跟结构体的名称,然后在花括号内列出结构体的成员。每个成员都是一个变量声明,它可以是任何有效的C语言数据类型,甚至是其它的结构体。
例如,我们可以定义一个表示学生信息的结构体:
struct Student { char name[50]; int age; long student_id; float gpa; };
在这个例子中,我们定义了一个名为 Student 的结构体,它包含四个成员:name(字符数组)、age(整数)、student_id(长整数)和 gpa(浮点数)。
2. 结构体变量的声明
定义好结构体后,我们就可以声明该结构体类型的变量了。声明结构体变量的方式有两种:
a) 在定义结构体的同时声明变量:
struct Student { char name[50]; int age; long student_id; float gpa; } student1, student2;
b) 使用已定义的结构体类型声明变量:
struct Student student1, student2;
3. 结构体的初始化/赋值
结构体变量可以在声明时进行初始化,也可以在声明后逐个赋值。初始化时,我们需要按照结构体成员的顺序提供初始值。以下是常见的初始化方式:
a) 声明时初始化:
struct Student student1 = {"John Doe", 20, 12345678, 3.75};
b) 声明后逐个赋值:
struct Student student2; strcpy(student2.name, "Jane Smith"); student2.age = 22; student2.student_id = 87654321; student2.gpa = 3.9;
注意,对于字符数组成员(如 name),我们需要使用 strcpy 函数来赋值,因为简单的赋值操作(=)不适用于数组。
c) 在 C99 标准及其以后的版本中,还可以使用指定初始化器:
struct Student student2 = { .name = "Bob", .age = 21, .student_id = 202100002, .gpa = 3.9 };这种方法允许我们通过成员名称来初始化特定的结构体成员,而不必遵循成员的声明顺序;即使以后在定义中修改了结构体成员的顺序,也不用修改代码了。
4. 结构体成员的访问
通过结构体变量访问成员时,我们需要使用点运算符.
,它的语法格式如下:
结构体变量名.成员名
例如,要打印学生的信息,我们可以这样做:
printf("Name: %s\n", student1.name); printf("Age: %d\n", student1.age); printf("Student ID: %ld\n", student1.student_id); printf("GPA: %.2f\n", student1.gpa);
输出结果:
Name: John Doe Age: 20 Student ID: 12345678 GPA: 3.75
在C语言中,我们也可以创建指向结构体的指针,它的的语法如下:
struct 结构体名 *指针变量名;
例如:
struct Student *ptr_student; ptr_student = &student1;
使用结构体指针访问成员时,我们使用箭头运算符->
,而不是点运算符。例如:
printf("Name: %s\n", ptr_student->name); printf("Age: %d\n", ptr_student->age);
5. 综合示例
文章最后,让我们通过一个综合示例来展示结构体的各种用法:
#include <stdio.h> #include <string.h> // 定义图书结构体 struct Book { char title[50]; char author[50]; int year; float price; }; // 函数原型 void printBook(const struct Book *book); void updatePrice(struct Book *book, float newPrice); int main() { // 声明并初始化结构体变量 struct Book book1 = {"C Programming", "Dennis Ritchie", 1972, 29.99}; struct Book book2; // 使用点号运算符初始化 book2 strcpy(book2.title, "The C Programming Language"); strcpy(book2.author, "Brian Kernighan"); book2.year = 1988; book2.price = 59.99; // 打印图书信息 printf("Book 1 information:\n"); printBook(&book1); printf("\nBook 2 information:\n"); printBook(&book2); // 更新价格 updatePrice(&book1, 34.99); updatePrice(&book2, 49.99); printf("\nAfter price update:\n"); printf("Book 1 new price: $%.2f\n", book1.price); printf("Book 2 new price: $%.2f\n", book2.price); return 0; } // 打印图书信息的函数 void printBook(const struct Book *book) { printf("Title: %s\n", book->title); printf("Author: %s\n", book->author); printf("Year: %d\n", book->year); printf("Price: $%.2f\n", book->price); } // 更新图书价格的函数 void updatePrice(struct Book *book, float newPrice) { book->price = newPrice; }
输出结果:
Book 1 information: Title: C Programming Author: Dennis Ritchie Year: 1972 Price: $29.99 Book 2 information: Title: The C Programming Language Author: Brian Kernighan Year: 1988 Price: $59.99 After price update: Book 1 new price: $34.99 Book 2 new price: $49.99
这个综合示例展示了结构体的定义、初始化、成员访问(使用点号和箭头运算符)、结构体指针作为函数参数等用法。
总起来说,结构体是一种自定义的、复合的数据类型,而不是变量。变量可以直接使用,而数据类型还需要声明变量才能使用。理解这一点非常重要,这是结构体的本质。
在实际编程中,结构体常常用于表示现实世界的对象或复杂的数据结构,如学生信息、商品详情、图形元素等。