学习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
#include
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
#include
#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
#include
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
#include
//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
#include
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
#include
#include
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);//显示(大小,未知)
}
}