数组三要素:连续内存、具体长度、相同类型。
1.结构体
- 含义:
一整块连续的内存,其中包含任意不同的数据类型。
(面向对象语言C++/C#/Java/Python中,有一种类似概念:类Class)
- 如何使用?
// 构造一个结构体模板(声明一种结构体类型) struct student{ char name[32]; //成员1:char [32]类型的数组 int age; //成员2:int整型 float score; //成员3:float浮点型 };
解析:
struct :结构体关键字
student :结构体标签(可任意取名称)
{....} :结构体成员
(关键字+标签: 结构体类型)
练习:
- 声明一个结构体类型,
成员1:学号 int
成员2:姓名 char [32]
成员3:性别 char
成员4:分数 float
- 定义一个50个元素的结构体数组,存储3个学生信息到数组中。
- 编写函数 show_info,以如下形式把所有学生信息打印出来。
ID Name Sex Score
1 Jack m 90.5
2 Rose w 85.5
3 Tom m 81.0
2.共用体
关键字:union,也称为联合体
// 构造一个共用体模板(声明一种共用体类型) union example{ int a; char b; double c; }x;
特点:
内存共用,操作互斥。
备注:
共用体的大小由其最大成员决定。
共用体主要用于节省内存空间,在单片机控制代码中比较常见。
练习:
- 声明结构体模板,存储下列信息:(s:学生 t:教师)
用户ID 用户名 用户标识 分数/所教科目(使用共用体存储)
1 Jack s 90.5
2 Rose t Math
3 Tom s 70.0
3.枚举
也称为,枚举常量列表
(使用时,与整型是一样的。)
备注:
如果没有指定枚举列表中的值,数值就会从0开始递增1。
如果单独指定某个值,后续数值也会逐个递增。
枚举类型用途非常少,并且很多场合也被宏定义替代了。
4.结构体大小计算
demo1_结构体使用
#include <stdio.h> #include <string.h> // 构造一个结构体模板(声明一种结构体类型) struct student{ char name[32]; int age; float score; }; int main() { // 数组定义1(未初始化) int arr1[5]; arr1[0] = 2; // *(arr1+0) 引用了数组中的第0元素 //.... // 数组定义2并初始化(元素类型:int 元素个数:5 数组类型:int [5]) int arr2[5] = {1, 3, 5, 7, 9}; // 数组定义3:指定元素初始化 int arr3[5] = {[0]=1, [4]=9}; // 结构体变量定义1(未初始化) struct student Jack; // .表示引用成员 strcpy(Jack.name, "Jack"); // Jack.name = "Jack"; // 错误的!数组名不能作为等号的左值 Jack.age = 18; Jack.score = 90.5; // 结构体变量定义2,并初始化(当模板中,成员顺序更改时,可能会出错!) struct student Rose = {"Rose", 16, 80.0}; // 结构体变量定义3:指定成员初始化 struct student Michael = { .score=88.5, .name="Michael" }; // 结构体变量赋值 struct student Michael2 = Michael; // 结构体数组 struct student myclass[50]; myclass[0] = Jack; myclass[1] = Rose; myclass[2] = Michael; // 结构体指针 struct student *p; p = &Michael; printf("%.1f\n", Michael.score); printf("%.1f\n", (*p).score); // 不常用。先对指针进行解引用,再使用.访问成员 printf("%.1f\n", p->score); // 更常用。只适用于结构体指针 return 0; }
demo2_结构体管理信息
#include <stdio.h> #include <string.h> // 构造一个结构体模板(声明一种结构体类型) struct stu{ int id; // 成员1:学号 char name[32]; // 成员2:姓名 char sex; // 成员3:性别 float score; // 成员4:分数 }; // 显示信息(地址传递,效率更高!) void show_info(struct stu *show); int main() { struct stu myClass[50] = { { .id=1, .name="Jack", .sex='m', .score=90.5 }, { .id=2, .name="Rose", .sex='w', .score=85.5 }, { .id=3, .name="Tom", .sex='m', .score=81.0 } }; // 显示信息 // show_info(&myClass[0]); show_info(myClass); return 0; } // 显示信息(值传递,会涉及内存的拷贝,如结构体过大,会导致操作效率低下!) // void show_info(struct stu show) // { // printf("ID\t Name\t Sex\t Score\n"); // printf("%d\t %s\t %c\t %.1f\n", show.id, show.name, show.sex, show.score); // } // 显示信息(地址传递,效率更高!) void show_info(struct stu *show) { printf("ID\t Name\t Sex\t Score\n"); int i; // for(i=0; i<3; i++) // { // printf("%d\t %s\t %c\t %.1f\n", show->id, show->name, show->sex, show->score); // show++; // } // for(i=0; i<3; i++) // { // printf("%d\t %s\t %c\t %.1f\n", // (show+i)->id, // (show+i)->name, // (show+i)->sex, // (show+i)->score); // } for(i=0; i<3; i++) { printf("%d\t %s\t %c\t %.1f\n", show[i].id, show[i].name, show[i].sex, show[i].score); } }
demo3_共用体
#include <stdio.h> #include <string.h> // 构造一个共用体模板(声明一种共用体类型) union example{ int a; char b; double c; }x; int main() { printf("%ld\n", sizeof(x)); printf("%ld\n", sizeof(union example)); x.a = 1; printf("x.a:%d\n", x.a); x.b = 100; printf("x.a:%d\n", x.a); return 0; }
demo4_结构体中添加共用体
#include <stdio.h> #include <string.h> struct usr_info{ int id; // 用户ID char name[20]; // 用户名 char sign; // 用户标识(s:学生 t:教师) // 当不需要再定义该类型时,标签可省略。 union{ float score; char subject[10]; }value; // 分数/所教科目(共用体) }; void show_info(struct usr_info *usr); int main() { struct usr_info usr[3] = { { .id=1, .name="Jack", .sign='s', .value.score = 90.5 }, { .id=2, .name="Rose", .sign='t', .value.subject="Math" }, { .id=3, .name="Tom", .sign='s', .value.score = 70.0 } }; show_info(usr); return 0; } void show_info(struct usr_info *usr) { printf("ID\t Name\t Sign\t Score/Subject\n"); int i; for(i=0; i<3; i++) { printf("%d\t %s\t %c\t ", usr[i].id, usr[i].name, usr[i].sign); if(usr[i].sign == 's') printf("%.1f\n", usr[i].value.score); else if(usr[i].sign == 't') printf("%s\n", usr[i].value.subject); } }
demo5_枚举
#include <stdio.h> #include <string.h> // 定义枚举常量列举(整型) enum spectrum{red, green=100, blue}; // int red = 0; // int green = 100; // int blue = 101; int main() { printf("%d\n", red); printf("%d\n", green); printf("%d\n", blue); return 0; }