8.结构体,共同体。
8.1 结构体 struct。
- 结构体可以理解为自定义的数据类型;
- 他是由一批数据组合而成的结构型数据。
- 里面的每个数据,都是结构体成员。
#include<string.h>
struct GirlFriend {
char name[100];
int age;
char gender;
double height;
};
int main(){
struct GirlFriend gf1; // 使用结构体。
strcpy(gf1.name, "小丽"); // 字符串赋值。
gf1.gender = 'F';
gf1.height = 1.63;
gf1.age = 22;
printf("女朋友名字:%s\n", gf1.name);
}
8.1.1 结构体数组。
struct Student {
char name[100];
int age;
};
int main(){
struct Student stu1 = {"张三", 23};
struct Student stu2 = {"李思", 24};
struct Student stu3 = {"王武", 25};
struct Student strArr[3] = {stu1,stu2,stu3};
for(int i=0;i<3;i++) {
struct Student temp = strArr[i];
printf("学生名字:%s, %d\n", temp.name, temp.age);
}
}
8.1.2 结构体的别名。typedef
typedef struct GirlFriend { // 可以省略GirlFriend名称。
char name[100];
} 别名;
typedef struct {
char name[100];
} GF;
GF gf1; // 使用由别名的结构体
typedef struct {
char name[100];
int attack;
int defense;
int blood
} M ;
int main(){
M m1 = {"泰罗", 100,90,80};
M m2 = {"雷欧", 102,88,77};
M m3 = {"迪曼", 101,10,99};
M arr[3] = {m1, m2, m3};
for(int i=0;i<3;i++) {
M temp = arr[i];
printf("奥特曼名字:%s,攻击力:%d,防御:%d,血量:%d.\n", temp.name,temp.attack,temp.defense,temp.blood);
}
}
8.1.3 结构体作为函数的参数。
-
直接传递值。 method(m1); 不会修改原有m1中的值。
void method(M m1){ // 修改m1中参数的值。}
传递结构体类型的变量,相当于定义了一个新的变量。不会修改原有变量中的值。 -
传递结构体指针。内存的地址。修改了值,
void method2(M* p){ // 传递指针,
printf("信息:%s, %d", (*p).name, (*p).age);
scanf("%s", (*p).name ); // 通过输入,修改名称。
scanf("%d", &((*p).age) ); // 年龄修改。
}
S stu;
strcpy(stu.name, "ABC");
stu.age = 10;
method2(&stu); // 调用函数,通过指针修改结构体的值。
8.1.4 结构体嵌套。
struct Message {
char phone[12];
char mail[100];
};
struct student {
char name[100];
struct Message msg; // 结构体嵌套。
};
Student stu;
strcpy(stu.msg.phone, "13366665555"); // 使用结构体嵌套。
strcpy(stu.msg.email, "123@qq.com");
printf("联系方式:电话:%s,邮箱:%s\n", stu.msg.phone, stu.msg.email);
// 批量赋值。也要嵌套赋值。
struct Student stu2 = {"lisi",24, "M",1.65, {"10086", "456@qq.com"}};
// 访问值:stu2.name, stu2.age; stu2.msg.phone
8.1.5 eg:景点投票。
#include<stdlib.h>
#include<time.h>
struct spot {
char name[100];
int count;
} ;
int main() {
struct spot arr[4] = {{"A",0}, {"B",0}, {"C",0}, {"D",0}};
srand(time(NULL));
for(int i=0; i<80; i++) {
int choose = rand() %4; // 0~3
arr[choose].count ++; // choose表示同学的投票,也表示数组中的索引。
}
int max = arr[0].count;
for(int i=0; i<4; i++) {
struct spot temp = arr[i];
if(temp.count > max) {
max = temp.count; // 拿到最大值。
}
}
// 遍历数组,谁的票数是最大值。
for(int i=0; i<4; i++) {
struct spot temp = arr[i];
if(temp.count == max) {
printf("投屏最多的景点:%s, %d", temp.name, temp.count);
break;
}
}
for(int i=0; i<4; i++) {
struct spot temp = arr[i];
printf("景点%s, %d", temp.name, temp.count);
}
}
8.1.6 结构体,内存对齐。
内存对齐:不管是结构体,还是普通的变量,都存在内存对齐。
规则:只能放在自己类型 整数倍 的内存地址上。
int 存放的位置,内存地址一定能被4整除;
long long存放的位置,内存地址一定能被8整除;
double存放的额位置,内存地址一定能被8整除。
确定变量位置:只能放在自己类型 整数倍 的内存地址上。
最后一个部位:结构体的总大小,是最大类型的整数倍。确定最后一个数据后面的空白字节补位情况。
struct num { // 一共占据24个字节。
double a; // 占8字节
char b; // 占1字节。+3空白字节。
int c; // 占4字节。
char d; // 占1字节。+7个空白字节。
};
printf("%zu\n", sizeof(n));
↓ 优化。
struct num { // 一共占据16字节。
char b;
char d;
int c;
double a;
};
规律:写结构体的时候,把小的数据类型,写到最上面;大的数据类型,写到下面。以节省空间。
9.共同体: union
一个数据可能有多重类型。每次只能选一种赋值。
有一种数据,可能出现多种形态。
金融项目的金额:int,double,字符串
考试成绩:100, 92.5, “A”
#include<string.h>
typedef union MeneyType {
double moneyd;
int moneyi; // 不能重名
char moneystr[100];
} MT;
union MeneyType m;
// m.moneyi = 789;
// printf("%d\n", m.moneyi);
// m.moneyd = 123.5;
// printf("%lf\n", m.moneyd);
strcpy(m.moneystr, "一万元");
printf("%s\n", m.moneystr);
9.1 共同体特点
- 共同体:也叫联合体,共用体。
- 所有的变量都使用同一个内存空间。
- 所占的空间大小= 最大成员的长度(也受内存对齐的影响)
- 每次只能给一个变量进行赋值,因为第二次赋值时会覆盖原有的数据。
9.2 结构体与共同体 的区别。
结构体:一种事物包含多个属性。
共同体:一个属性有多种类型。
存储方式:
结构体:各存储各的,
共用体:存一起,多次存会覆盖之前的数据。
内存占用:
结构体:各个内存的总和(受到内存对齐的影响)
共用体:最大类型占用的空间(受到内存对齐的影响)
网友评论