C基础知识(8):结构体、共用体、位域
结构体
数组允许定义可存储相同类型数据项的变量,而结构体是C编程中另一种用户自定义的可用的数据类型,它允许用户可以存储不同类型的数据项。
struct 语句的格式如下:
1 struct [structure tag] 2 { 3 member definition; 4 member definition; 5 ... 6 member definition; 7 } [one or more structure variables];
其中,structure tag 是可选的。在结构定义的末尾,最后一个分号之前,还可以指定一个或多个结构变量,这是可选的。
下面是一个定义结构和访问结构成员的例子:
1 #include <stdio.h> 2 #include <string.h> 3 4 struct Books { 5 int id; 6 char title[50]; 7 char author[50]; 8 char subject[100]; 9 }; 10 11 int main() { 12 // 声明book1,类型为 Books 13 struct Books book1; 14 // 添加信息到book1 15 book1.id = 100001; 16 strcpy(book1.title, "Learn C program"); 17 strcpy(book1.author, "Zhang San"); 18 strcpy(book1.subject, "IT/Program"); 19 // 输出book1信息 20 printf("%d\n", book1.id); // 100001 21 printf("%s\n", book1.title); // Learn C program 22 printf("%s\n", book1.author); // Zhang San 23 printf("%s\n", book1.subject); // IT/Program 24 }
使用typedef关键字可以为类型取一个新的名字。例如,可以对结构体使用typedef来定义一个新的数据类型名字,然后使用这个新的数据类型来直接定义结构变量。
1 #include <stdio.h> 2 #include <string.h> 3 4 typedef struct Books { 5 int id; 6 char title[50]; 7 char author[50]; 8 char subject[100]; 9 } Book; 10 11 int main() { 12 // 声明book1,类型为 Books 13 Book book1; 14 // 添加信息到book1 15 book1.id = 100001; 16 strcpy(book1.title, "Learn C program"); 17 strcpy(book1.author, "Zhang San"); 18 strcpy(book1.subject, "IT/Program"); 19 // 输出book1信息 20 printf("%d\n", book1.id); // 100001 21 printf("%s\n", book1.title); // Learn C program 22 printf("%s\n", book1.author); // Zhang San 23 printf("%s\n", book1.subject); // IT/Program 24 return 0; 25 }
结构也可以作为函数参数,并使用指针。指针变量访问结构的成员,必须使用 -> 运算符。
1 #include <stdio.h> 2 #include <string.h> 3 4 struct Books { 5 int id; 6 char title[50]; 7 char author[50]; 8 char subject[100]; 9 }; 10 11 void printBook(struct Books *book); 12 13 int main() { 14 // 声明book1,类型为 Books 15 struct Books book1; 16 // 添加信息到book1 17 book1.id = 100001; 18 strcpy(book1.title, "Learn C program"); 19 strcpy(book1.author, "Zhang San"); 20 strcpy(book1.subject, "IT/Program"); 21 printBook(&book1); 22 } 23 24 void printBook(struct Books *book) { 25 printf("%s\n", book->title); 26 printf("%s\n", book->author); 27 printf("%s\n", book->subject); 28 printf("%d\n", book->id); 29 }
共用体
共用体是一种特殊的数据类型,允许用户在相同的内存位置存储不同的数据类型。可以定义一个带有多成员的共用体,但是任何时候只能有一个成员带有值。共用体提供了一种使用相同的内存位置的有效方式。
1 #include <stdio.h> 2 #include <string.h> 3 4 // 从下面例子可以看出 5 // (1) 共用体占用的内存为共用体中最大的成员所占的内存。 6 // (2) 最后赋的值才是有效值。 7 union Data { 8 int i; // 4 Byte 9 float f; // 4 Byte 10 char c[20]; // 20 Byte 11 }; 12 13 int main() { 14 union Data data; 15 printf("Memory: %d\n", sizeof(data)); // 20 16 data.i = 10; 17 data.f = 20.5; 18 strcpy(data.c, "This is a C program."); 19 printf("data.i: %d\n", data.i); // 损坏值 20 printf("data.f: %f\n", data.f); // 损坏值 21 printf("data.c: %s\n", data.c); // This is a C program. 22 return 0; 23 }
位域
把一个(或多个)字节中的二进位划分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。这样就可以把几个不同的对象用一个(或多个)字节的二进制位域来表示。
注意事项:
(1) 一个位域必须存储在同一个字节中,不能跨两个字节。(说明一个位域不能超过8位)
(2) 一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。(也可以用空域占位,使某位域从下一单元开始。)
1 #include <stdio.h> 2 3 struct bs { 4 unsigned a :1; 5 unsigned b :4; 6 unsigned :3; // 空域 7 unsigned c :8; 8 } bit, *pbit; 9 int main() { 10 bit.a = 1; 11 bit.b = 15; 12 bit.c = 255; 13 printf("%d\t%d\t%d\n", bit.a, bit.b, bit.c); // 1 15 255 14 pbit = &bit; // *pbit要初始化! 15 pbit->a = 0; 16 pbit->b &= 7; // 与运算 17 pbit->c |= 7; // 或运算 18 printf("%d\t%d\t%d\n", pbit->a, pbit->b, pbit->c); // 0 7 255 19 }