zoukankan      html  css  js  c++  java
  • 指针

    定义一个指向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;
    }

    猜完了记得反汇编验证自己的想法。

  • 相关阅读:
    软件架构设计模式简述
    [翻译]docker生态圈Mindmap
    完美解决Invalid layout of java.lang.String at value问题的方法
    用开源项目JazzyViewPager实现ViewPager切换动画
    用开源项目RangBar来实现有范围的SeekBar
    开源项目MultiChoiceAdapter详解(六)——GridView和MultiChoiceBaseAdapter配合使用
    开源项目MultiChoiceAdapter详解(五)——可扩展的MultiChoiceBaseAdapter
    开源项目MultiChoiceAdapter详解(四)——MultiChoiceBaseAdapter的使用
    开源项目MultiChoiceAdapter详解(三)——MulitChoiceNormalArrayAdapter的使用
    开源项目MultiChoiceAdapter详解(二)——MultiChoiceArrayAdapter的使用
  • 原文地址:https://www.cnblogs.com/ZRBYYXDM/p/5228623.html
Copyright © 2011-2022 走看看