C 语言中的结构体
C 语言中的结构体
C 语言中的结构体是一种派生数据类型或用户自定义数据类型。我们使用关键字 struct 来定义一种自定义数据类型,将不同类型的元素组合在一起。数组和结构体的区别在于,数组是相似类型的同质集合,而结构体可以相邻存储不同类型的元素,并通过名称进行标识。
我们经常需要处理不同数据类型的值,这些值之间存在一定的关系。例如,一本 book 由其 title(字符串)、author(字符串)、price(双精度型)、number of pages(整数型)等描述。这些值可以存储在一个 struct 变量中,而无需使用四个不同的变量。
声明(创建)结构体
您可以使用 "struct" 关键字加上structure_tag(结构体名称)来创建(声明)结构体,并在花括号内声明结构体的所有成员及其数据类型。
要定义结构体,必须使用 struct 语句。 struct 语句定义了一个新的数据类型,该类型包含多个成员。
结构体声明的语法
声明结构的格式(语法)如下:-
struct [structure tag]{ member definition; member definition; ... member definition; } [one or more structure variables];
结构体标签是可选的,每个成员定义都是一个普通的变量定义,例如"int i;"或"float f;"。或任何其他有效的变量定义。
在结构体定义的末尾,在最后一个分号之前,您可以指定一个或多个结构体变量,但这是可选的。
示例
在下面的示例中,我们为 Book 声明了一个结构体来存储书籍的详细信息 -
struct book{ char title[50]; char author[50]; double price; int pages; } book1;
此处,我们在结构体定义的末尾声明了结构体变量 book1。不过,您也可以在不同的语句中单独声明。
结构体变量声明
要访问和操作结构体成员,需要先声明其变量。声明结构体变量时,请将结构体名称与 "struct" 关键字一起写入,后跟结构体变量的名称。此结构体变量将用于访问和操作结构体成员。
示例
以下语句演示了如何声明(创建)结构体变量
struct book book1;
通常,结构体在程序中定义第一个函数之前声明,位于 include 语句之后。这样,派生类型便可用于在任何函数内声明其变量。
结构体初始化
结构体变量的初始化是通过将每个元素的值放在大括号内来完成的。
示例
以下语句演示了结构体的初始化
struct book book1 = {"Learn C", "Dennis Ritchie", 675.50, 325};
访问结构体成员
要访问结构体成员,首先需要声明一个结构体变量,然后使用点 (.) 运算符以及该结构体变量。
示例 1
使用点 (.) 运算符访问结构体变量 book1 的四个元素。因此,"book1.title"指的是书名元素,"book1.author"是作者姓名,"book1.price"是价格,"book1.pages"是第四个元素(页数)。
请看以下示例 -
#include <stdio.h> struct book{ char title[10]; char author[20]; double price; int pages; }; int main(){ struct book book1 = {"Learn C", "Dennis Ritchie", 675.50, 325}; printf("Title: %s ", book1.title); printf("Author: %s ", book1.author); printf("Price: %lf ", book1.price); printf("Pages: %d ", book1.pages); printf("Size of book struct: %d", sizeof(struct book)); return 0; }
输出
运行代码并检查其输出 −
Title: Learn C Author: Dennis Ritchie Price: 675.500000 Pages: 325 Size of book struct: 48
示例 2
对上面的程序进行一些小修改。在这里,我们将类型定义和变量声明放在一起,如下所示 -
struct book{ char title[10]; char author[20]; double price; int pages; } book1;
请注意,如果您以这种方式声明结构体变量,则不能使用花括号初始化它。相反,需要对元素单独赋值。
#include <stdio.h> #include <string.h> struct book{ char title[10]; char author[20]; double price; int pages; } book1; int main(){ strcpy(book1.title, "Learn C"); strcpy(book1.author, "Dennis Ritchie"); book1.price = 675.50; book1.pages = 325; printf("Title: %s ", book1.title); printf("Author: %s ", book1.author); printf("Price: %lf ", book1.price); printf("Pages: %d ", book1.pages); return 0; }
输出
当您执行此代码时,它将产生以下输出 -
Title: Learn C Author: Dennis Ritchie Price: 675.500000 Pages: 325
复制结构体
赋值运算符 (=) 可用于直接复制结构体。您也可以使用赋值运算符 (=) 将一个结构体成员的值赋给另一个结构体。
假设有两个结构体 book 变量,book1 和 book2。变量 book1 已通过声明初始化,我们希望将其元素的值赋给 book2。
我们可以按如下方式对各个元素进行赋值 -
struct book book1 = {"Learn C", "Dennis Ritchie", 675.50, 325}, book2; strcpy(book2.title, book1.title); strcpy(book2.author, book1.author); book2.price = book1.price; book2.pages = book1.pages;
请注意,使用 strcpy() 函数 将值赋给 string 变量,而不是使用"="运算符。
示例
您还可以将 book1 赋值给 book2,这样 book1 的所有元素都会分别赋值给 book2 的元素。请看以下程序代码 -
#include <stdio.h> #include <string.h> struct book{ char title[10]; char author[20]; double price; int pages; }; int main(){ struct book book1 = {"Learn C", "Dennis Ritchie", 675.50, 325}, book2; book2 = book1; printf("Title: %s ", book2.title); printf("Author: %s ", book2.author); printf("Price: %lf ", book1.price); printf("Pages: %d ", book1.pages); printf("Size of book struct: %d", sizeof(struct book)); return 0; }
输出
运行代码并检查其输出 −
Title: Learn C Author: Dennis Ritchie Price: 675.500000 Pages: 325 Size of book struct: 48
结构体作为函数参数
您可以像传递其他变量或指针一样,将结构体作为函数参数传递。
示例
查看以下程序代码。它演示了如何将结构体作为函数参数传递 -
#include <stdio.h> #include <string.h> struct Books{ char title[50]; char author[50]; char subject[100]; int book_id; }; /* 函数声明 */ void printBook(struct Books book); int main(){ struct Books Book1; /* 将 Book1 声明为 Book 类型 */ struct Books Book2; /* 将 Book2 声明为 Book 类型 */ /* 书 1 的说明 */ strcpy(Book1.title, "C Programming"); strcpy(Book1.author, "Nuha Ali"); strcpy(Book1.subject, "C Programming Tutorial"); Book1.book_id = 6495407; /* 书 2 的说明 */ strcpy(Book2.title, "Telecom Billing"); strcpy(Book2.author, "Zara Ali"); strcpy(Book2.subject, "Telecom Billing Tutorial"); Book2.book_id = 6495700; /* 打印 Book1 的信息 */ printBook(Book1); /* 打印 Book2 的信息 */ printBook(Book2); return 0; } void printBook(struct Books book){ printf("Book title : %s ", book.title); printf("Book author : %s ", book.author); printf("Book subject : %s ", book.subject); printf("Book book_id : %d ", book.book_id); }
输出
当编译并执行上述代码时,它会产生以下结果 -
Book title : C Programming Book author : Nuha Ali Book subject : C Programming Tutorial Book book_id : 6495407 Book title : Telecom Billing Book author : Zara Ali Book subject : Telecom Billing Tutorial Book book_id : 6495700
指向结构的指针
指向结构的指针的声明
您可以按如下方式声明指向结构的指针(或结构指针):
struct Books *struct_pointer;
指向结构的指针的初始化
您可以将结构变量的地址存储在上述指针变量struct_pointer中。要查找结构变量的地址,请在"&"结构体名称前的运算符如下:-
struct_pointer = & book1;
让我们将结构体变量的地址存储在结构体指针变量中。
struct book{ char title[10]; char author[20]; double price; int pages; }; struct book book1 = {"Learn C", "Dennis Ritchie", 675.50, 325}, struct book *strptr;
使用指向结构体的指针访问成员
要使用指向结构体的指针访问结构体的成员,必须使用 运算符,如下所示 -
struct_pointer->title;
C 语言将 符号定义为与结构体指针一起使用的 间接运算符(也称为 结构体解引用运算符)。它有助于访问指针引用的结构体变量的元素。
示例
在此示例中,strptr 是指向 struct book book1 变量的指针。因此,strrptrtitle 返回标题,就像 book1.title 一样。
#include <stdio.h> #include <string.h> struct book{ char title[10]; char author[20]; double price; int pages; }; int main (){ struct book book1 = {"Learn C", "Dennis Ritchie", 675.50, 325}; struct book *strptr; strptr = &book1; printf("Title: %s ", strptr -> title); printf("Author: %s ", strptr -> author); printf("Price: %lf ", strptr -> price); printf("Pages: %d ", strptr -> pages); return 0; }
输出
运行此代码时,将产生以下输出 -
Title: Learn C Author: Dennis Ritchie Price: 675.500000 Pages: 325
注意:点运算符 (.) 用于通过 struct 变量访问结构体元素。要通过其指针访问元素,必须使用 间接寻址 (->) 运算符
。结构体变量类似于普通的主类型变量,您可以拥有一个结构体数组,可以将结构体变量传递给函数,也可以从函数返回一个结构体。
您可能已经注意到,在声明变量或指针时,需要在名称前加上"结构体类型"前缀。可以通过使用 typedef 关键字创建简写符号来避免这种情况,我们将在后续章节中对此进行解释。
结构体用于不同的应用程序,例如数据库、文件管理应用程序,以及处理复杂的数据结构,例如树形结构和链表。
位域
位域 允许将数据打包到结构体中。当内存或数据存储紧张时,这尤其有用。典型示例包括:-
- 将多个对象打包成一个机器字,例如,可以压缩 1 位标志。
- 读取外部文件格式 - 可以读取非标准文件格式,例如 9 位整数。
声明
C 语言允许我们在结构体定义中通过在变量后添加 :bit length 来实现此目的。例如:-
struct packed_struct{ unsigned int f1:1; unsigned int f2:1; unsigned int f3:1; unsigned int f4:1; unsigned int type:4; unsigned int my_int:9; } pack;
此处,packed_struct 包含 6 个成员:四个 1 位标志 f1..f3、一个 4 位类型和一个 9 位 my_int。
C 语言会自动尽可能紧凑地打包上述位字段,前提是这些字段的最大长度小于或等于计算机的整数字长。如果不是这种情况,某些编译器可能会允许这些字段的内存重叠,而其他编译器则会将下一个字段存储在下一个字中。