一、线性表
当涉及到C语言数据结构时,线性表、栈、队列和树是常见的基本数据结构。下面是关于这些数据结构的一些基本知识:
-
线性表:
- 线性表是一种数据结构,其中的元素按照线性顺序排列。每个元素都有一个前驱和一个后继(除了第一个和最后一个元素)。
- 在C语言中,线性表通常通过数组或链表实现。
- 线性表的常见操作包括插入、删除、查找、访问等。
数组实现的线性表示例:(以下均以C语言示范)
#define MAX_SIZE 100
typedef struct {
int data[MAX_SIZE];
int length;
} ArrayLinearList;
链表实现的线性表示例:
typedef struct Node {
int data;
struct Node* next;
} LinkedListNode;
typedef struct {
LinkedListNode* head;
LinkedListNode* tail;
int length;
} LinkedListLinearList;
二、栈
- 栈是一种具有后进先出(LIFO)特性的数据结构。最后放入栈的元素首先被移除。
- 在C语言中,栈通常通过数组或链表实现。使用数组实现的栈称为顺序栈,而使用链表实现的栈称为链式栈。
- 栈的常见操作包括入栈(将元素添加到栈顶)、出栈(从栈顶移除元素)、获取栈顶元素、判断栈是否为空等。
顺序栈实例:
#define MAX_SIZE 100
typedef struct {
int data[MAX_SIZE];
int top;
} ArrayStack;
链式栈示例:
typedef struct Node {
int data;
struct Node* next;
} LinkedListNode;
typedef struct {
LinkedListNode* top;
} LinkedListStack;
三、队列
- 队列是一种具有先进先出(FIFO)特性的数据结构。最早放入队列的元素首先被移除。
- 在C语言中,队列通常通过数组或链表实现。使用数组实现的队列称为顺序队列,而使用链表实现的队列称为链式队列。
- 队列的常见操作包括入队(将元素添加到队尾)、出队(从队头移除元素)、获取队头元素、判断队列是否为空等。
顺序队列实例:
#define MAX_SIZE 100
typedef struct {
int data[MAX_SIZE];
int front;
int rear;
} ArrayQueue;
链式队列实例:
typedef struct Node {
int data;
struct Node* next;
} LinkedListNode;
typedef struct {
LinkedListNode* front;
LinkedListNode* rear;
} LinkedListQueue;
四、树
typedef struct TreeNode {
int data;
struct TreeNode* left;
struct TreeNode* right;
} BinaryTree;
- 树是一种分层的数据结构,由节点组成,其中每个节点可能具有零个或多个子节点。
- 树的一个节点称为根节点,它没有父节点。其他节点分为内部节点和叶节点,内部节点具有一个或多个子节点,叶节点没有子节点。
- 在C语言中,树通常通过指针和动态内存分配来实现。常见的树结构包括二叉树、二叉搜索树、AVL树、红黑树等。
- 树的常见操作包括插入节点、删除节点、查找节点、遍历树等。
二叉树实例:
typedef struct TreeNode {
int data;
struct TreeNode* left;
struct TreeNode* right;
} BinaryTree;
二叉搜索树实例:
typedef struct TreeNode {
int data;
struct TreeNode* left;
struct TreeNode* right;
} BinarySearchTree;
四、IDA基本操作
一、和硬编码有关的几个指令
先从
options
→
general
界面中把硬编码调出来(最大为
16
)
用途:
IDA
对文件的分析也是有可能出错的,我们可以用这几个指令更改这些错误
a
指令:当前数据用字符串显示
c
指令:当前数据用代码显示
d
指令:当前数据用数据显示
u
指令:未定义,
IDA
只把硬编码的十六进制列出来,不做分析
二、比较重要的分析指令
1.按键F5
在
IDA
中可以通过快捷键
F5
把某个函数直接生成为
C
语言代码,这样做在某些时候可以让我们分析代码更方便。虽然这样直接生成得到的C
语言代码的可读性不是很强,并且可能还会忽略
IDA
没有识别到的指令,但是解题的时候可以让你更快的理解意思,所以对于题目中要分析的文件,都可以直接按f5
生成伪代码。除了F5
,也可以使用
tab
键来切换汇编和伪码
2.按键n
分析汇编是比较麻烦的一件事,如果我们要分析的文件很大,有很多个函数,如果不做标记的话可能会导致前功尽弃。我们要通过做标记的方法让自己之后再看时可以迅速想起这个函数的功能,类似于写注释当分析完一个函数后,可以点击这个函数的名称,然后按下n
,给这个函数进行重新命名,通过重新命名的方式就能想起这个函数的功能另外也可以用n
指令给寄存器(类似于变量)命名,增强可读性
3.注释的;和:
除了可以用
n
取名字的方式帮助记忆外,
IDA
也可以通过注释的方式来帮助记忆。
注释有两种方式,一种是分号
";"
,另一种是冒号
":"
。两种方式都是按键之后让你输入文本,并且不管使用哪种方式,最后呈现出来的注释效果都是下面这种形式:两种方式的区别在于,如果使用分号进行注释,如果被注释的这一行被其他行引用,那么添加注释后注释内容也会被拷贝;如果是用冒号进行注释,那么注释内容就不会被拷贝过去。另外,如果是想对整个函数进行注释,就在函数名那里按键,生成的注释会在函数体上方
4.shift+f12
列出所有字符串。这个所有字符串不只是指定义的赋过值的字符串,还有包括在一些输入输出语句的提示字符串。
5.结构体相关的指令
1.添加结构体
添加结构体的步骤:
按
Insert
键,输入结构体名称
逐步添加结构体的变量
添加结构体变量的方法:
让光标停在最后一行甚至之后(但要在结构体的虚线之内),然后按
d
即可创建一个大小为
1
字节,
名字默认的结构体变量,接下来我们要对这个结构体变量进行修改
对结构体变量进行修改
首先让光标停在你要修改的那一行,按
n
命令对变量名字进行修改,改成你想要的名字,接下来指
定变量类型。
注意汇编是没有
int
、
double
这些显示的数据类型声明的,我们在这里指定变量类型只用指定变量
的大小。对于基本的数据类型,按
d
键调整它的大小就行了(
double
这种
8
字节的可以按
y
键再输入
double
)
db
、
dw
、
dd
、
dq
分别代表
1
、
2
、
4
、
8
字节。如果变量是数组,先按
d
调整到每个单元对
应的大小,再按
*
键输入数组大小即可。如果是字符串,按
a
键输入字符数组的大小,就成字符串
了。对于结构体中的变量是结构体的,可以按
alt+q
选择结构体
2.结构体引用
在默认视图窗口选择你认为可能用到这个结构体的变量,选择
alt+q
为它选择结构体
3.交叉引用
可以通过
ctrl+x
查看函数和全局变量都在哪里被引用过,即交叉引用
4.其他辅助的指令和快捷键
g
指令:跳转指令
ESC
:返回上个界面
Alt+t
:搜索的快捷键,几个选项的含义
区分大小写
正则表达式:可以简单的理解为用一套规定的符号去进行模糊匹配,后面会学的
标识符
向上搜索:搜索光标以上的内容
查找所有事件