【指针1】 指针减法 数组索引与数组指针 指针的强制转换

一、同类型指针可以做减法:

比如:

#include <iostream>
using namespace std;
int arr[1230];
int main() {
	int *a = &arr[4];
	int *b = (arr + 1);
	int c = a - b;
	cout << c << endl; // c 的值为 4-1 = 3
	getchar();
	return 0;
}

甚至可以不是一个数组里的


#include <iostream>
using namespace std;
int arr[1230];
int acc[234];
int main() {
	int *a = &arr[0];
	int *b = (acc + 0);
	int c = a - b;

	/* 
	全局变量是连续的地址
	至于换成是局部变量就可能无法预测
	*/

	cout << c << endl; 
	/*c = -1230 */

	getchar();
	return 0;
}


有兴趣的我看了下反汇编代码

01141856  mov         eax,dword ptr [a]  
01141859  sub         eax,dword ptr [b]  
0114185C  sar         eax,2  
0114185F  mov         dword ptr [c],eax  

其实很简单。。。每段地址都是由一个十六进制数保存的。
计算机就是把这两个东西地址相减,然后除以4也就是sizeof(int) 作为返回值。
【注:这里的mov: mov dest , source ,略有不同】


二、指针访问数组确实比索引快

	a1 = arr[4];
00A81EFC  mov         eax,4  
00A81F01  shl         eax,2  
00A81F04  mov         ecx,dword ptr arr (0A8A138h)[eax]  
00A81F0A  mov         dword ptr [a1],ecx  
	a2 = *(arr + 4);
00A81F0D  mov         eax,dword ptr ds:[00A8A148h]  
00A81F12  mov         dword ptr [a2],eax  

索引法还多了一次求下标操作。

指针法直接通过移位寻址。

【当然通常不会计较这么点东西,了解一下】


三、实现 “伪AL AH”

#include <iostream>
using namespace std;
void getNum(const int * num, short& AL, short& AH)
{
    short* ptr = (short*)num;
    AL = *ptr++;
    AH = *ptr;
}
int main() {
    short AL = 0, AH = 0;

    int num = 0x1f2f3f4f;

    getNum(&num, AL, AH);
    printf("%x\n%x\n", AL, AH);
    /* AH = 0x1f2f  AL = 0x3f4f */

    getchar();
    return 0;
}

结论:其实指针就是地址,和它的修饰符没有关系。无论是int,char ,longlong地址还是这个地址。

           修饰符的作用个人暂时理解为:走到下一个位置应该保留的区域大小

           比如int* , 一下就是4个字节 short* 2个字节 , char* 一个字节。

上述这段代码强制把4个字节一跳改为2个字节一跳,自然而然就取到了高位和低位(你甚至可以直接修改AL AH)

getNum反汇编代码如下

	short* ptr = (short*)num;
00FE18FE  mov         eax,dword ptr [num]  
00FE1901  mov         dword ptr [ptr],eax   //地址还是这个地址,不会因类型转换而变
	AL = *ptr++;
00FE1904  mov         eax,dword ptr [AL]    //eax:AL地址 (因为我们穿的是引用)
00FE1907  mov         ecx,dword ptr [ptr]   //ecx:ptr地址
00FE190A  mov         dx,word ptr [ecx]     //ptr的值的低4个字节 赋给 dx
00FE190D  mov         word ptr [eax],dx     //把dx赋给 AL 地址指向的值
00FE1910  mov         eax,dword ptr [ptr]   
00FE1913  add         eax,2  		    //ptr 后移 两个字节(short)
00FE1916  mov         dword ptr [ptr],eax   //..后同
	AH = *ptr;
00FE1919  mov         eax,dword ptr [AH]  
00FE191C  mov         ecx,dword ptr [ptr]  
00FE191F  mov         dx,word ptr [ecx]  
00FE1922  mov         word ptr [eax],dx  


不得不说了解汇编是理解指针的重要武器



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值