当前位置: 首页 > article >正文

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;
};

输出的结果:

 

我们现在查看内存:

我们会发现,他们的结构体也是挨着的,也就是说

如果找到了一个怪物的一个属性,那么也就找到了所有的属性。

如果找到了一个怪物的属性,那么也就找到了所有怪物的属性。


http://www.kler.cn/a/441703.html

相关文章:

  • 66,【6】buuctf web [HarekazeCTF2019]Avatar Uploader 1
  • 在Ubuntu上安装RabbitMQ教程
  • 服务器日志自动上传到阿里云OSS备份
  • postman的使用
  • 基于python的博客系统设计与实现
  • 使用插件SlideVerify实现滑块验证
  • Uniapp安卓端获取手机号码
  • Docker中 localhost 与 0.0.0.0 的区别详解
  • oracle client linux服务器安装教程
  • git SSL certificate problem: unable to get local issuer certificate
  • 只出现一次的数字(字节面试题 最优解)
  • OpenCV 功能函数介绍 (二)
  • awk使用详解
  • 【WPF】RenderTargetBitmap的使用
  • 如何让你的 PHP 应用坚不可摧
  • 【网络安全】掌握 Active Directory 攻防审计实操知识点
  • MaskGCT——开源文本转语音模型,可模仿任何人说话声音
  • 宝塔 搭建HOJ 配置域名 反向代理 开启https访问
  • Android使用PorterDuffXfermode的模式PorterDuff.Mode.SRC_OUT实现橡皮擦,Kotlin(1)
  • Flink-Learning全面探索流式处理的卓越框架
  • 【win10+RAGFlow+Ollama】搭建本地大模型助手(教程+源码)
  • CTFHub-ssrf
  • mysql flink cdc 实时数据抓取
  • 大模型QLoRA微调——基于Qwen2-7B的自动化病历摘要生成系统
  • OpenCV与Qt5构建卡尺找直线工具
  • 7.OPEN SQL