目录
结构体(struct)类型的基本使用
为什么需要结构体?
C语言内置的数据类型,除了几种原始的基本数据类型,只有数组属于复合类型,可以同时包含多个值,但是只能包含相同类型的数据,实际使用场景受限。
举例1:
现有一个需求,编写学生档案管理系统,这里需要描述一个学生的信息。该学生的信息包括学号、姓名、性别、年龄、家庭住址等,这些数据共同说明一个学生的总体情况。
表格
学号 | 姓名 | 性别 | 年龄 | 家庭住址 |
1001 | 大壮 | 男 | 10 | ... |
1002 | 小明 | 男 | 11 | ... |
1003 | 丽丽 | 女 | 12 | ... |
显然,这些数据类型各不相同,无法使用数组进行统一管理。
举例2:
老王养了两只猫咪。一只名字叫小黄,今年2岁,橘色;另一只叫小黑,今年3岁,黑色。请编写一个程序,当用户输入小猫的名字时,就显示该猫的名字,年龄,颜色。如果用户输入的小猫名错误,则显示老王没有这只猫。
传统的解决方法
尝试1:单独定义多个变量存储,实现需求。但是,多个变量,不便于数据的管理。
尝试2:使用数组,它是一组具有相同类型的数据的集合。但在编程中,往往还需要一组类型不同的数据。比如猫的名字使用字符串、年龄是int,颜色是字符串,因为数据类型不同,不能用一个数组来存放。
尝试3:C语言提供了结构体。使用结构体,内部可以定义多个不同类型的变量作为其成员。
结构体的理解
定义:
C语言提供了 struct 关键字,允许自定义复合数据类型,将不同类型的值组合在一起,这种类型称为结构体(structure)类型。
比如:
- 提取猫的特征 → Cat结构体 → 变量1(名字)、变量2(年龄)……
- 提取人的特征 → Person结构体 → 变量1(名字)、变量2(年龄)……
声明结构体
构建一个结构体类型的一般格式:
struct 结构体名{
数据类型1 成员名1; //分号结尾
数据类型2 成员名2;
...
数据类型n 成员名n;
}; //注意最后有一个分号
举例:学生
struct student{ // 定义结构体:学生
int id; //学号
char name[20];//姓名
char gender; //性别
char* address;//家庭住址
};
举例:猫
struct Cat{
char name[20];//名字
int age; //年龄
char* color; //颜色
};
定义了新的数据类型以后,就可以声明该类型的变量,这与声明其他类型变量的写法是一样的。
struct Student stu1;
调用结构体变量的成员:
结构体变量名.成员名 [= 常量或变量值]
实例:
#include <stdio.h>
int main() {
struct Student stu1; //声明结构体变量
struct Student stu2; //声明结构体变量
//调用结构体成员
stu1.id = 1001;
strcpy(stu1.name, "Tom");
stu1.gender = 'M';
stu1.address = "陕西省 汉中市";
printf("id = %d,name = %s,gender = %c,address = %s\n",
stu1.id, stu1.name, stu1.gender, stu1.address);
return 0;
}
说明:
- 先声明了一个 struct Student 类型的变量 stu1 ,这时编译器就会为 stu1 分配内存,接着就可以为 stu1 的不同属性赋值。可以看到, struct 结构的属性通过点( . )来表示,比如 id 属性要写成 stu1.id 。
- 字符数组是一种特殊的数组,直接改掉字符数组名的地址会报错,因此不能直接通过赋值运算符来对它进行赋值。你可以使用字符串库函数 strcpy() 来进行字符串的复制操作。
其他方式声明结构体变量
其他方式声明结构体变量格式1:
除了逐一对属性赋值,也可以使用大括号,一次性对 struct 结构的所有属性赋值。此时,初始化的属性个数最好与结构体中成员个数相同,且成员的先后顺序一一对应。
格式:
struct 结构体名 结构体变量 = {初始化数据};
举例:
// 声明结构体
struct Car {
char* name;
double price;
int speed;
};
// 声明结构体变量
struct Car audi = {"audi A6L", 460000.99, 175};
struct Student {
int id;
char* name;
char gender;
int score; //学生成绩
};
int main() {
struct Student stu = {1001, "songhk", 'M'};
printf("Name: %s\n", stu.name);
//注意:若大括号内值数量少于属性数量,缺失属性自动初始化默认值。
printf("score: %d\n", stu.score);
return 0;
}
其他方式声明结构体变量格式2:
指定属性名赋值
格式:
struct 结构体名 结构体变量={.成员1=xxx,.成员2=yyy,....};
举例:
struct Car audi = {.speed=175,.name="audi A6L"};
可修改属性值:
c
struct Car audi = {.speed=175,.name="audi A6L"};
audi.speed = 185; //将 speed 属性值改成 185
其他方式声明结构体变量格式3:
声明类型的同时定义结构体变量
struct 的数据类型声明语句与变量的声明语句可合并,
格式:
struct 结构体名 {
成员列表
} 结构体变量名列表;
举例
struct Employee {
char* name;
int age;
char gender;
char* phone;
} emp1, emp2;
int main() {
emp1.name = "jim";
emp1.age = 20;
emp1.gender ='m';
emp1.phone = "1523335555";
return 0;
}
其他方式声明结构体变量格式4:
不指定类型名而直接定义结构体类型变量(匿名结构体)
格式:
struct {
成员列表;
} 变量名列表;
举例:
struct {
char* name;
int age;
char gender;
char* phone;
} emp1, emp2;
//可在声明变量时赋值:
struct {
char* name;
int age;
char gender;
char* phone;
} emp1 = {"Lucy", 23, 'F', "13012341234"},
emp2 = {"Tony", 25, 'M', "13678967899"};
注:上述在声明变量emp1和emp2的同时,为他们赋值
其他方式声明结构体变量格式5:
使用 typedef 命令
使用typedef可以为struct结构指定一个别名,这样使用起来更简洁
格式:
typedef struct EmployeeInfo {
char* name;
int age;
char gender;
char* phone;
} Employee;
typedef 简化结构体声明:
typedef struct EmployeeInfo {
char* name;
int age;
char gender;
char* phone;
} Employee;
//声明结构体变量
Employee emp = {"Lucy", 23, 'F', "13012341234"};
匿名结构体结合 typedef :
typedef struct {
char* name;
int age;
char gender;
char* phone;
} Employee;
//声明结构体变量
Employee emp = {"张三", 20, 'M', "18333336666"};
实例(计算立方体体积)
#include <stdio.h>
typedef struct {
int length;
int width;
int height;
} Box;
int getVolume(Box box) {
return box.length * box.width * box.height;
}
int main() {
Box box;
printf("请输入长:");
scanf("%d", &box.length);
printf("请输入宽:");
scanf("%d", &box.width);
printf("请输入高:");
scanf("%d", &box.height);
printf("立方体积为:%d", getVolume(box));
return 0;
}