C语言学习day19:结构体/枚举/共用体/游戏结构体的逆向分析
结构体
在C语言中,结构体(struct) 是一种用户自定义的数据类型,它可以将不同类型的数据组合成一个单一的复合类型。结构体允许我们将相关的数据存储在一起,并为其指定一个名字,以便在程序中进行访问和操作。
结构体的定义和使用
1. 结构体的定义
结构体通过 struct
关键字定义,后跟结构体名称和一对花括号,花括号内是结构体的成员(字段)。
#include <stdio.h>
// 定义一个结构体
struct Student {
char name[50]; // 学生姓名
int age; // 学生年龄
float grade; // 学生成绩
};
int main() {
struct Student s1; // 声明一个结构体变量
// 为结构体成员赋值
strcpy(s1.name, "Alice");
s1.age = 20;
s1.grade = 88.5;
// 输出结构体成员
printf("Name: %s\n", s1.name);
printf("Age: %d\n", s1.age);
printf("Grade: %.2f\n", s1.grade);
return 0;
}
也可以这么声明:
struct Person {
char name[50];
int age;
float height;
} p1, p2; // 同时声明 p1 和 p2
2. 访问结构体成员
结构体的成员可以使用点运算符(.
)进行访问。如果你有一个结构体的指针,可以使用箭头运算符(->
)。
struct Student *sPtr = &s1;
printf("Name: %s\n", sPtr->name); // 使用指针访问结构体成员
3. 结构体数组
结构体数组可以用来存储多个结构体实例。例如,以下代码定义了一个学生结构体的数组:
struct Student students[3]; // 定义一个学生数组
// 为每个学生赋值
for (int i = 0; i < 3; i++) {
printf("Enter name, age, grade for student %d:\n", i + 1);
scanf("%s %d %f", students[i].name, &students[i].age, &students[i].grade);
}
4. 结构体嵌套
结构体可以包含其他结构体。这种嵌套结构可以方便地组织复杂数据。
struct Address {
char street[100];
char city[50];
};
struct Student {
char name[50];
int age;
struct Address addr; // 嵌套结构体
};
// 使用示例
struct Student s;
strcpy(s.addr.street, "123 Main St");
strcpy(s.addr.city, "New York");
5. 关键点
- 结构体可以用于封装相关数据。
- 每个成员可以是不同的数据类型。
- 可以通过定义结构体数组,嵌套结构体来处理复杂数据。
实践
结构体1:
现在我们开始实践一般的用法情况:
请看下面代码:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <wchar.h> // 需要引入宽字符库
#include <locale.h> // 需要包含 locale.h 头文件
#include <windows.h>//window api函数
struct monster
{
int blood;
//double coordinate[3];
int aa;
int if_death;//byte类型,不是0就是1
};
int main()
{
//直接给数据
/*struct monster Mon1 = {
18,
2,3,4,
0
};*/
struct monster Mon1;
Mon1.blood = 18;
//Mon1.coordinate[0] = 1;
//Mon1.coordinate[1] = 2;
//Mon1.coordinate[2] = 3;
Mon1.aa = 8888;
Mon1.if_death = 0;
struct monster* add2 = &Mon1;
getchar();
return 1;
};
我们查看它的内存:
我们发现,在结构体中,它的所有的属性都是挨着的。
结构体数组1:
很多情况下,我们不可能只有一个结构体,比如说游戏,游戏中不会只有一个怪,一定有很多的怪物,这时,一个结构体很明显是不够的,所有结构体数组也就出现了:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <wchar.h> // 需要引入宽字符库
#include <locale.h> // 需要包含 locale.h 头文件
#include <windows.h>//window api函数
struct monster
{
int blood;
//double coordinate[3];
int age;
int if_death;//byte类型,不是0就是1
};
int main()
{
struct monster Mon1[3];
/*printf("%d\n", sizeof(Mon1)/sizeof(Mon1[0]));*/
struct monster* add2=&Mon1;
for (size_t i = 0; i < sizeof(Mon1) / sizeof(Mon1[0]); i++)
{
printf("请输入怪物%d的血量、年龄、状态\n", i + 1);
scanf("%d %d %d", &add2->blood, &add2->age, &add2->if_death);
add2++;移动指针,不然会被覆盖
}
重置指针add2
add2 = Mon1;
for (size_t i = 0; i < sizeof(Mon1) / sizeof(Mon1[0]); i++)
{
printf("怪物%d的血量为%d,年龄为%d,状态为%d\n", i + 1, add2->blood, add2->age, add2->if_death);
}
getchar();
return 1;
};
输出的结果:
我们现在查看内存:
我们会发现,他们的结构体也是挨着的,也就是说
如果找到了一个怪物的一个属性,那么也就找到了所有的属性。
如果找到了一个怪物的属性,那么也就找到了所有怪物的属性。