定义一个指向int的指针变量:
int i = 100;
int *p = &i;
以下代码将输出变量 i 的值:
# include <iostream>
using namespace std;
int main( int argc,char *argv[] )
{
int i = 100;
int *p = &i;
cout << *p << endl;
return 0;
}
对输出语句下断,调试运行,断下之后查看其反汇编代码:
10: cout << *p << endl;
00401585 push offset @ILT+195(std::endl) (004010c8)
0040158A mov ecx,dword ptr [ebp-8]
0040158D mov edx,dword ptr [ecx]
0040158F push edx
00401590 mov ecx,offset std::cout (0047be90)
00401595 call @ILT+250(std::basic_ostream<char,std::char_traits<char> >::operator<<) (004010ff)
0040159A mov ecx,eax
0040159C call @ILT+475(std::basic_ostream<char,std::char_traits<char> >::operator<<) (004011e0)
其中,*p生成了58A-58D这两条汇编指令。
再来看看指向指针的指针解引用产生的代码:
11: cout << **Ptr << endl;
0040158B push offset @ILT+195(std::endl) (004010c8)
00401590 mov edx,dword ptr [ebp-0Ch]
00401593 mov eax,dword ptr [edx]
00401595 mov ecx,dword ptr [eax]
00401597 push ecx
00401598 mov ecx,offset std::cout (0047be90)
0040159D call @ILT+250(std::basic_ostream<char,std::char_traits<char> >::operator<<) (004010ff)
004015A2 mov ecx,eax
004015A4 call @ILT+475(std::basic_ostream<char,std::char_traits<char> >::operator<<) (004011e0)
这下就产生了三条汇编指令,也就是说,*的出现次数N + 1就是产生汇编指令的条数。
定义一个指针指向char数组的首地址,并令其自增:
# include <iostream>
using namespace std;
int main( int argc,char *argv[] )
{
char *p = "123";
p++;
return 0;
}
对自增操作下断,并查看反汇编:
9: p++;
0040104F mov eax,dword ptr [ebp-4]
00401052 add eax,1
00401055 mov dword ptr [ebp-4],eax
自增操作将指针移动一个字节。
再定义一个指针指向int数组的首地址,并令其自增,查看其反汇编:
10: p++;
0040105C mov ecx,dword ptr [ebp-0Ch]
0040105F add ecx,4
00401062 mov dword ptr [ebp-0Ch],ecx
自增操作将指针移动四个字节,那我们就可以得出结论,指针自增移动的字节数 = 其指向的数据的字节数。
再来,定义一个数组指针指向一个数组:
# include <iostream>
using namespace std;
int main( int argc,char *argv[] )
{
int arr[2] = { 1,2 };
int (*ptr)[2] = ( int (*)[2] )arr;
cout << **ptr << endl;
return 0;
}
这段代码将输出数据首个元素1.
改动代码令数组指针自增:
# include <iostream>
using namespace std;
int main( int argc,char *argv[] )
{
int arr[4] = { 1,2,3,4 };
int (*ptr)[2] = ( int (*)[2] )arr;
cout << *( *(ptr+1) ) << endl;
return 0;
}
这段代码输出的结果又是什么呢?不急,我们先来查查输出语句的反汇编:
10: cout << *( *(ptr+1) ) << endl;
0040159A push offset @ILT+195(std::endl) (004010c8)
0040159F mov ecx,dword ptr [ebp-14h]
004015A2 mov edx,dword ptr [ecx+8]
004015A5 push edx
004015A6 mov ecx,offset std::cout (0047be90)
004015AB call @ILT+250(std::basic_ostream<char,std::char_traits<char> >::operator<<) (004010ff)
004015B0 mov ecx,eax
004015B2 call @ILT+475(std::basic_ostream<char,std::char_traits<char> >::operator<<) (004011e0)
结果是指针移动了8个字节,是数组的第三个元素3.也就是说,数组指针移动的字节数 = 定义时[]里的N * 加上的数 * 定义时数据类型的字节数
这里,N为2,加上的数是1,int类型的字节为4.
2 * 1 * 4 = 8.
有了上面的知识,你可以尝试着猜猜这段程序输出的是什么:
# include <iostream>
using namespace std;
int main( int argc,char *argv[] )
{
char *str = "123456789";
char (*ptr)[3] = ( char (*)[3] )str;
cout << *( *(ptr+2) + 1 ) << endl;
return 0;
}
猜完了记得反汇编验证自己的想法。