滴水逆向三期笔记与作业——02C语言——12 指针(2)

OneNote防丢。

一、类型转换

略,无需总结,多用即熟悉。

二、&符号的使用

&是地址符,类型是其后面的类型加一个“*”,任何变量都可以使用&来获取地址,但不能用在常量上。

char a = 10;
short b = 20;
int c = 30;

char* pa = &a;
short* pb = &b;
int* pc = &c;        
//&pa 是char*类型
//&pb 是short*类型
//&pc 是int*类型
char a = 10;
short b = 20;
int c = 30;

char* pa = (char*)&a;
short* pb = (short*)&b;
int* pc = (int*)&c;

/*简写为:*/
char* pa = &a;
short* pb = &b;
int* pc = &c;
char a = 10;
short b = 20;
int c = 30;

char* pa = &a;
short* pb = &b;
int* pc = &c;

char** ppa = (char**)&pa;
short** ppb = (short**)&pb;
int** ppc = (int**)&pc;


/*简写为:*/
char** ppa = &pa;
short** ppb = &pb;
int** ppc = &pc;

三、指针求值

int* px;
int** px2;
int*** px3;
int**** px4;

//*(px) 是int类型
//*(px2) 是int*类型
//*(px3) 是int**类型
//*(px4) 是int***类型
  • 观察反汇编
int x,y;
int* px;
int** px2;
int*** px3;

x = 10;
px = &x;
px2 = &px;
px3 = &px2;
y = *(*(*(px3)));

在这里插入图片描述

  • 解析:

x:rbp-0x8
y:rbp-0x4
px:rbp-0x10,存放了8字节的rbp-0x8地址
px2:rbp-0x18,存放了8字节的rbp-0x10地址
px3:rbp-0x20,存放了8字节的rbp-0x18地址
最后在给y赋值时,通过地址寻址找到10的路径是:[rbp-0x20]—>[rbp-0x18]—>[rbp-0x10]—>[rbp-0x8]

  • 总结:
    类型的变量,可以通过在其变量前加来获取其指向内存中存储的值
    在带类型的变量前面加,类型是其原来的类型减去一个*

四、指针操作数组

char arr[10];
char* p = &arr[0]; //取数组第一个元素的地址
char* p2 = arr;    //简写
char* p = arr;
for(int k=0;k<10;k++)
{
printf("%d\n",*(p+k));
}

short* p = arr;
for(int k=0;k<10;k++)
{
printf("%d\n",*(p+k));
}

int* p = arr;
for(int k=0;k<10;k++)
{
printf("%d\n",*(p+k));
}

五、作业

1、列出每一行的反汇编代码:

char a = 10;
short b = 20;
int c = 30;
char* pa = &a;
short* pb = &b;
int* pc = &c;

char** ppa = &pa;
short** ppb = &pb;
int** ppc = &pc;

在这里插入图片描述

2、列出每一行的反汇编代码:

int p = 10;
int******* p7;
int****** p6;
int***** p5;
int**** p4;
int*** p3;
int** p2;
int* p1;

p1 = &p;
p2 = &p1;
p3 = &p2;
p4 = &p3;
p5 = &p4;
p6 = &p5;
p7 = &p6;

在这里插入图片描述

3、完成代码,实现数组值的互换

void Function()
{
	int arr[5] = {1,2,3,4,5};
	//..此处添加代码,使用指针,将数组的值倒置
	//打印数组值的代码已经写完,不需要修改
	for(int k=0;k<5;k++)
	{
		printf("%d\n",*(p+k));
	}
}
void Function()
{
	int arr[5] = {1,2,3,4,5};
	int* p = arr;
	int temp;
	int* q = &arr[4];

	//..此处添加代码,使用指针,将数组的值倒置
	//将p++和q--写到for判断体中,*q = temp这句代码会报指针分段错误,crazy,没弄明白。

	for (int i = 0; i <= 5/2; i++)
	{
		temp = *p;
		*p = *q;
		*q = temp;
		p++;
		q--;
	}
	p = arr;

	//打印数组值的代码已经写完,不需要修改
	for(int k=0;k<5;k++)
	{
		printf("%d\n",*(p+k));
	}
}

int main(int argc, char* argv[]){
	Function();
	return 0;
}

 

 

//不用中间指针的方式
void Function()
{
	int arr[5] = {1,2,3,4,5};
	int* p = arr,temp;
	// ..此处添加代码,使用指针,将数组的值倒置
	for (int i = 0; i<5/2; i++)
	{
		temp = *(arr + i);
		*(arr + i) = *(arr + 4 - i);
		*(arr + 4 - i) = temp;
	}
	//打印数组值的代码已经写完,不需要修改
	for(int k=0;k<5;k++)
	{
		printf("%d\n",*(p+k));
	}
}

int main(int argc, char* argv[]){
	Function();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值