```c++
今天遇到了一个关于游戏安全问题,有个老师说
可以通过把数据打乱的方式保证它不会被索到
比如int gold=1000
当我们用CE搜1000时,可能就会找到gold的真实地址,
但是如果我们把gold在内存中的存储方式打乱,比如
gold四个字节,每个字节拆分开,然后把每个字节打乱并将每一份保存起来
当需要显示gold时,再把保存好的一份重新组合就能显示
我知识水平不够,不理解的地方是,当把它重新组合的时候,组合完毕后
不就再内存中有一个完整的gold了吗,不还是能被搜索到??
一种可以实现“先进后出”的存储结构
分类:
栈的核心操作:
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
typedef struct Node
{
int data;
struct Node* pNext;
} NODE,*PNODE;
typedef struct Stack
{
PNODE pTop;
PNODE pBottom;
}STACK,*PSTACK;
void init(PSTACK pS); //初始化一个栈
void push(PSTACK pS, int val); //入栈
bool empty(PSTACK pS); //判断栈是否为空
void traverse(PSTACK pS); //遍历一个栈
bool pop(PSTACK pS, int* pval);//出栈
void clear_one(PSTACK pS); //清空栈第一种实现
void clear_two(PSTACK pS); //清空栈第二种实现
int main(void)
{
STACK S;
init(&S);
traverse(&S);
push(&S,1);
push(&S,2);
push(&S,3);
push(&S,4);
push(&S,5);
push(&S,6);
traverse(&S);
int i;
pop(&S,&i);
pop(&S,&i);
printf_s("出栈元素是%d", i);
pop(&S,&i);
pop(&S,&i);
traverse(&S);
push(&S, 1);
push(&S, 2);
push(&S, 3);
push(&S, 4);
push(&S, 5);
push(&S, 6);
traverse(&S);
clear_one(&S);
traverse(&S);
push(&S, 1);
push(&S, 2);
push(&S, 3);
push(&S, 4);
push(&S, 5);
push(&S, 6);
traverse(&S);
clear_two(&S);
traverse(&S);
return 0;
}
//初始化一个栈
void init(PSTACK pS)
{
pS->pTop = (PNODE)malloc(sizeof(NODE));
if (NULL== pS->pTop)
{
printf_s("动态分配内存失败");
exit(-1);
}
else
{
pS->pBottom = pS->pTop;
//将pTop指向的节点的指针域赋空(使其不链着下一个节点)
pS->pTop->pNext = NULL;
}
}
//入栈
//pS:指向栈的指针
//val:入栈元素的值
void push(PSTACK pS, int val)
{
PNODE pNew = (PNODE)malloc(sizeof(NODE));
if (NULL== pNew)
{
printf_s("动态分配内存失败");
exit(-1);
}
pNew->data = val;
pNew->pNext = pS->pTop;
pS->pTop = pNew;
return;
}
//判断栈是否为空
bool empty(PSTACK pS)
{
if (pS->pTop == pS->pBottom)
{
return true;
}
else
{
return false;
}
}
//遍历一个栈
void traverse(PSTACK pS)
{
if (empty(pS))
{
printf_s("栈为空!");
return;
}
PNODE p = pS->pTop;
while (p!=pS->pBottom)
{
printf_s("%d \n", p->data);
p = p->pNext;
}
}
//出栈
//pS:指向栈的指针
//pval:出栈元素的指针
bool pop(PSTACK pS, int* pval)
{
if (empty(pS))
{
return false;
}
else
{
PNODE p = pS->pTop;
*pval = p->data;
pS->pTop = pS->pTop->pNext;
free(p);
p = NULL;
return true;
}
}
//清空栈第一种实现
//r为一个指针,永远指向p下一个节点
void clear_one(PSTACK pS)
{
if (empty(pS))
{
printf_s("栈为空!");
return;
}
PNODE p = pS->pTop;
PNODE r = NULL;
while (p!=pS->pBottom)
{
r = p->pNext;
free(p);
p = r;
}
pS->pTop = pS->pBottom;
return;
}
//清空栈第二种实现,比较好理解
//r用于保存要释放内存的节点
void clear_two(PSTACK pS)
{
if (empty(pS))
{
printf_s("栈为空!");
return;
}
PNODE p = pS->pTop;
PNODE r = NULL;
while (p != pS->pBottom)
{
r = p;
p = p->pNext;
free(r);
r = NULL;
}
pS->pTop = pS->pBottom;
return;
}
栈的应用:
1.函数调用
2.中断
3.表达式求值
4.内存分配
5.缓冲处理
6.走迷宫问题