4-16-指针、函数与指针、游戏外挂、define与typedef、const

学习4-16期视频笔记

1、指针

指针:一个变量的地址                &num

指针变量:专门存放变量地址的变量    p

32位操作系统

00000000 0000 0000  0000 0000 0000 0000

11111111 1111 1111  1111 1111 1111 1111

4G=2^2G=2^2*2^10M=2^2*2^10*2^10K=2^2*2^10^2^10*2^10B=2^32B

4G内存以下用32位操作系统,4G内存以上最好使用64位系统

 

(1)打印指针以及地址


     int num = 5;
       int *p = #   //通过寄存器取num地址,进行赋值
//取地址在cpu的寄存器中产生,不占内存。
//地址计算机总线,地址作为常量不消耗内存
//p是一个常量,间接赋值,存储不同的地址
     printf(“%d,%d\n”*p,num,);//打印num的数据 5
//0x001234AB
       printf("%p,&p\n", p,&num);//打印num的全部地址(8个16进制位)001234AB
       printf("%x,&x\n", p,&num);//打印num的非零地址(不打印开始的0)1234AB
 
       printf("%p\n", &p); //打印指针p的地址,该地址存储的内容使num的地址

          地址       内容

&p->00CFF88C->00CFF898

p  ->00CFF898->5           即num的地址

打印p的值,p的值就是num的地址(&num)

 

       int num1 = 100;
       int num2 = 200;
       int * p = &num1; //指针是变量
       p = &num2;//p的值 存储一个地址,占四个字节
       *p = 12;//*p将12传递给指针p所存储的地址,即将12传递给num2,此时num2=12
       //间接修改数据, *p根据地址进行赋值,根据类型进行解析
 
       //double * p,类型决定步长,解析方式不同


p=&num为目标地址,*p=3为目标地址的数据

 

(2)指针类型(与数据对应),大小(4)

int num=10;
double *p; //没有对象的野指针
*p=#
printf(“%f”,*p);//结果为垃圾数据,
int*px=#
printf(“%d”,*px);//结果为10.类型要对应
printf("%d\n",sizeof(p)); //4, 任何类型指针的大小都是四个字节,因为任何类型的地址都是四个字节
printf("%d\n",sizeof(*p)); //8,*p表示数据,根据地址往前读8个字节,因为是double类型


 

(3)函数与指针

#include<stdlib.h>
#include<stdio.h>
 
int change(intnum) //副本机制,传值,函数里面的num只作用于函数内部
{
       num = 4;
     printf("change=%d\n", num);//4
}
int changep(int*p)  //也有副本机制,只不过将数值传递到数据地址(地址可以间接赋值)进行修改
{
       *p = 3;
}
void main()
{
       int num = 10;
       int *p = #
       change(num);  只作用于函数内部,对外界无效
       printf("%d\n", num);//10   
       changep(&num); //修改内存中num的数值
       printf("changep=%d\n", num);//3  
       system("pause");
}


 

(4)修改游戏数据

使用MemSearch通过俩次内存搜索,确定内存位置

_declspec(dllexport)void go()
{
int *p=0xae1234;//需要修改的变量的地址,需要注意类型
*p=99;  //将数据随意修改(在限定范围内)
}

或者:如果知道大致范围,以及当前值

_declspec(dllexport)void run()
{
    for(char *p=0xae0000;p<0xae1000;p++)//内存大致范围
    {
        int *px=p;
        if(*px==77)
        {
            *px=86;
        }
    }
}


2、空类型指针

       //void a; //不合法,未定义大小
       //void *a;//合法,任何类型地址都一样
       int num = 10;
       double db = 9.33;
       void *p = #//合法,明确大小
       p = &db;// 可以存取任何类型
       //printf("%d", *p);  //errpr c2100 :非法的间接寻址
       //void *p   不能间接取值,也不能间接赋值(*p=10 不对)
       printf("%f", *((double*)p));//强制转化
       //指针类型的意义:明确类型和解析方式


 

3、野指针与空指针

       int *a;//野指针,可能会使程序崩溃
 
       double db = 10.9;
       double *p = NULL;//地址为0x00000000
       //空指针没有存储地址,空指针不能取地址(会与内存中原本的0x00000000冲突)
       //NULL 定义 #define NULL ((void *)0)
       while (p == NULL) //查看该指针是否有对象
       {
              p = &db;
       }


4、指针声明

     int a, b, c;
     double * pa, *pb, *pc;//三个都是指针
     double * pa,pb,pc;//这样只表示第一个是指针,后俩个是double类型


5、define与typedef

#include<stdlib.h>
#include<stdio.h>
#define 指针 double*   //只是一个替换
typedef double* INTP;    //给类型起个别名
//int *p;
//typedef int *p;
//typedef int * INTP;//别名
 
voidmain()
{
       指针 p1,p2;
       INTP p3,p4;
       printf("%d,%d\n", sizeof(p1),sizeof(p2));  //4,8
       printf("%d,%d", sizeof(p3),sizeof(p4));   //4,4
       system("pause");
}


 

define在前,typedef在后

 

6、银行报表

使用指针排序

#define  _CRT_SECURE_NO_WARNINGS
#include<stdlib.h>
#include<stdio.h>
 
void main()
{
       int num1;
       int num2;
       scanf("%d%d", &num1,&num2);//从小到大
       int *p1 = &num1;
       int *p2 = &num2;
       if (*p1 < *p2)
       {
              int *ptemp = p1;
              p1 = p2;
              p2 = ptemp;
       }
       printf("%d,%d", *p1, *p2);//前大后小
       system("pause");
}


 

使用const设置权限(只读)

#include<stdlib.h>
#include<stdio.h>
//int const *p与const int *p等价
void sec(constint *p)//const在*左边,限定数据只能读不能写
{
       printf("\n*p=%d", *p);
     p=NULL;//指向的数据不可改变,存储的地址可以改变
       //*p = 10;//加上const后,只能读,不能修改
}
void main()
{
       int num = 100;
       int *p = #
       sec(p);
       printf("num=%d", num);
       getchar();
}
 


使用指针冒泡排序排序

#include<stdlib.h>
#include<stdio.h>
 
int a[8] = {1,8,2,7,3,6,4,5 };
const int*p[8]={&a[0],&a[1],a+2,a+3,a+4,a+5,a+6,a+7};
void main()
{
       printf("数组数据");
       for (int i = 0; i < 8; i++)
       {     
              printf("%d,",a[i]);
       }
       for (int i = 0; i < 8 - 1; i++)
       {
              for (int j = 0; j < 8 - 1-i;j++)
              {
                     if (*p[j]>*p[j+1])
                     {
                            int *ptemp = p[j];
                            p[j] = p[j + 1];
                            p[j + 1] = ptemp;
                     }
              }
       }
       printf("数组数据");
       for (int i = 0; i < 8; i++)
       {
              printf("%d,",*p[i]);
       }
       system("pause");
}


 

7、桌面显示图片

#include<stdlib.h>
#include<stdio.h>
#include<Windows.h>
 
 
void main()
{
       while (1)
       {
              HWND win = GetDesktopWindow();//获取桌面
              HDC windc = GetWindowDC(win);//获取桌面的显示
              HDC Memdc = CreateCompatibleDC(0);//获取位图的句柄
              HBITMAPbit =(HBITMAP)LoadImage(win,TEXT("1.bmp"),IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION);//导入图片
              SelectObject(Memdc, bit); //设置显示内容
              BitBlt(windc, 0, 0, 1000, 700,Memdc, 0, 0, SRCCOPY);//显示(大小,未知)
       }
}


 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值