一.窗口弹出<ollyDBG调试工具>
包含函数#include<Windows.h>函数库
1.弹出窗口
调用函数MessageBox(),其中四个参数:第一个设置为0,窗口编号。第二个为弹出窗口内容,第三个参数为窗口标题,第三第二个需要用双引号,第四个设置为0,为窗口类型。
2. ShellExecute打开程序,文件或者网址等操作
ShellExecute(0,”open”,”www.baidu.com”,0,0,1)函数.open还可以换成打印”printf”
注意:C中的路径为\\双斜杠。
打开文件夹:
ShellExecute(0,”open”,”D:\\”,0,0,1)
打开可执行文件:
ShellExecute();将第三个参数换成程序的路径。
ShellExecute参数说明。
第一个参数:表示谁执行的,0表示系统执行
第二个参数:执行某操作,一般情况有 open和printf
第三个参数:执行的文件路径、名称、网址、邮件地址。
第四个和第五个为系统保留的参数:均为0
第六个:一般不起什么作用。有些时候控制窗口的最大最小化等。6为最小化,1反之。
#keybd_event()函数学习:键盘操作函数。
keybd_event('Z',0,0,0); 按下Z键。
keybd_event('Z',0,2,0); 松开Z键。合起来为按下一个Z键再弹起来。
#mouse_event()函数学习:鼠标操作函数
mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_MOVE,200*65535/1366,300*65535/768,0,0);该函数实现将鼠标移动到坐标为(200,300)的位置。
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);//鼠标左键点击
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);//鼠标左键弹起,完成一次鼠标点击的动作。
#windows.h学习:system(“startcalc”),其不用等下一次结束就开始执行下一次指令。
#include学习:自己写的头文件一般应用时用双引号“ ”。
反复包含问题:一个工程内多个.c函数调用同一个.h文件时,应该把声明放到.h文件中,将函数的实体放到一个新的.c文件中,这样多次调用时候避免重复包含。
#实际参数+形式参数:实际参数和形式参数的形式顺序and数量都得需要对应。函数调用的时候会自动产生赋值操作。实参会转换成形参类型。
Return语句:通过使用该语句,可以向函数的调用处返回一个值。
函数库学习:学习如何调用函数库,学会查找函数。<标准头文件+常用库函数>
C语言中函数参数的入栈顺序:从右至左的顺序。
具体参考博文:http://blog.sina.com.cn/s/blog_62b1508e0100gqxk.html
练习题目参考:
http://www.nowcoder.com/questionTerminal/9fd169364f4a42599aa7ade7f1c9bbd9?toCommentId=64575
#指针长度:指针表示的是一个操作系统的最大字长度,字是由几个字节组成 32位4个字节组成一个字,64位8个字节组成一个字。
*函数的声明可以有多个,但是定义只能有一个*/*函数名的本质是内存地址*/
#嵌套调用:一个函数调用另外一个函数
#递归调用:自己调用自己。
递归调用时,模仿goto语句,子函数中使用if-else语句。
递归调用的应用:腾讯面试题目:有一个50阶的楼梯,每次可以上一阶或者两阶,请问总共有多少中走法。代码:http://blog.sina.com.cn/s/blog_b29b05900102vvzd.html
任何循环都可以转换成递归,反之则不一定。
#区分库函数与自定义函数
#形式参数与实际参数
函数定义时,括号里的形式参数不确定值,不会分配内存。只有调用函数的时候才会分配内存,新建一个变量,接受实际参数的值。当函数调用结束时,形参占用的内存会被回收。
实际参数是函数调用时函数传递的确切值。可以是表达式或者常量
形参与实参内存不一样,占用不同的内存空间。
函数调用时,形式参数接受传递过来的实际参数的值,等价于新建一个变量,实际参数给形式参数赋值,赋值过程中自动完成数据类型转换。所以调用函数的时候尽量要类型匹配,否则出现误差或者错误。
#局部变量和全局变量
局部变量用完之后会被回收,其是为块语句服务的,快语句执行结束时,其被回收。
全局变量不属于任何一个函数,可以被任何一个函数所调用。
#外挂原理
根据地址:调用函数,修改数据
#内存与CPU读写速度快,断电即消失,容量比较小,成本比较高。
百度中央服务器的内存大概为1T。
高级服务器中,读写频繁的数据存放在内存中。
#32位计算机最大内存为4G=2^32字节,也就是内存地址由32个二进制位表达。
#&和*:&根据内容取出地址,*则是根据地址取出内容。
int num=100;
int*p=&num,此时有p=&num,*p=num。 //p是一个指针变量,可以指向任何一个变量。P指向一个变量,亦即该指针存储了该变量的地址。
#论指针前边类型符的重要性。比如int *p=100200,地址只是提供起始地址,而前边的类型符则规定该变量的长度,以此来寻址。Int的长度为4个字节。
指针例题:改变一个变量的数值,用一个指针指向它,然后改变。指针可以在外部改变内部变量。
#写外挂时,不用main()函数,将其换成go()即可,而且void之前加上_declspec(dllexport)
作为dll的输出,写dll文件时必须加上_declspec(dllexport)
函数。
外挂例子:http://blog.sina.com.cn/s/blog_b29b05900102vwjb.html
#指针
指针使用之前必须加以初始化。
指针是一个地址,大小是固定的,占用4个字节。
地址VS指针:地址是一个储存变量的常量,而指针是一个变量,指针常量。指针有类型(起始地址,长度等信息),而地址是没有类型的。地址只知道从哪里开始,而指针知道从哪里开始,从哪里结束。
指针申明时,例如:double *pa,pb,pc中只有pa是指针,其他两个不是指针。
空指针:int *p=NULL;指针初始化,不指向任何一个变量。
直接访问和间接访问:
直接访问:根据变量的地址访问变量。
打印时%x是按照十六进制打印地址,而%p是按照地址打印。
Printf(“%p,%x”,&num,p):%p显示地址的位数。
if (*pa<*pb) //指?针?交?换?
{
int *p=pa; //指针交换,一般需要中间变量。 pb=p;
}
Swap()函数一般用指针来实现。
#二级指针:容纳指针的地址。
用途:在函数的外部改变指针变量。
函数改变外部变量时,如果是一个数据,则传递数据的地址。如果是一个指针,则传递指针的地址。
一级指针储存变量的地址。
1.函数内部改变外部的指针变量
2.游戏外挂改变外部的指针变量。
#指针的类型和指针所指向的类型
类型不同,不能赋值。不同的类型大小不一样,解析方式也不一样。
两个指针指向同一个变量,通常用于数据通信,公用一个变量。两个指针指向同一个变量时,当其中的一个赋值发生变化时,其余都会跟着变化。
指针的类型必须要和指针指向的类型一样。Int类型和float都占四个字节,但是对应的指针解析方式不同。
#指针变量的值
指指针本身存储的数值,这个值将被编译器当成一个地址,而非普通的值。
32位程序里,内存地址的长度都为32位。
指针存储的是地址,是首地址。而类型决定了从哪里结束。此外类型决定了长度以及解析方式。
#指针运算
整数最好不要直接与指针进行计算。
相比较与.cpp而言,.c比较宽泛。一般都用cpp写C。.c比较宽泛,类型不匹配时只会警告。
#函数指针
#函数的返回值是指针:例如 string * mystr()
按照时间设定随机数种子,必须包含头文件<time.h>
Int a[10];
Time_t ts;
Srand((unsigned int)time(&ts));//按照时间设定随机数种子
For (inti=0;i<10;i++)
{
a[i]=rand()%100;
Printf(“%d\n”,a[i]);
}
#空类型指针。
char str='A';
int num=100;
double db=10.9;
void *p;
p=&str;//空类型指针可以指向任何类型的数据
p=#
p=&db;
//任何指针都可以赋值给空类型的指针用于保存地址。空类型指针可以转换为任何类型的指针。
#memset 对内存挨个赋值
比如memset(str,’A’,5); //从str首地址开始前进五个字节,对每一位赋值为字符‘A’。5表示5个字节,申明为 char str[20];
又比如有申明intnum[5]={1,2,3,4,5};
Memset(int,0,20);//表示对20个字节的五个整数都赋值为0.
Memset()函数的第一个参数为一个空指针,能接受任何类型的指针,如上例中的char或者int类型。
#malloc函数,分配内存。返回值也是void类型的指针。
Void *malloc(unsigned int size) //系统为程序开辟一块大小为size个内存字节的区域,并将该区域的首地址返回。
Int *p=(int *)malloc(5*sizeof(int)); //
Free(p);//不可以反复释放内存。
动态内存分配:指用户可以在程序运行期间根据需要申请或释放内存,大小完全可控。不需要像数组内存那样预先分配空间。
#指针的三要素:地址,步长,解析方式。
Malloc()函数返回的是一个空类型的指针,因此分配空间是要进行强制转换。
例:int*p=(int *)malloc(1024*1024*100);
#动态数组
int num;
Scanf(“%d”,&num);
Int *p=malloc(sizeof(int)*num);
For(int i=0;i<num;i++)
{
P[num]=i;
Printf(“%d,%x”,p[i],&p[i]);
}
Free(p);
#数组只能处理小数据
例如:当定义一个数组, inta[1024*1024*10];时,生成过程会报错。原因就是数组只能处理小数据。
例:intnum=100;
Int a[num]; //错,数组的大小必须明确。
因此引入动态内存分配。
#free函数使用手册:free函数只能释放一次,不能重复释放。
只有空指针时,反复释放没问题。
#局部静态变量
该局部静态变量的生命周期贯穿函数调用及之后的时间。其在程序执行第一次经过时被初始化,直到程序终止时才被销毁。在此期间即使对象所在的函数结束执行也不会对它有影响。