単にCでの参照やポインタを比較する++

エイリアス変数である参考書であるだけでC ++を学習する前に、この引数は、C ++やJava(登録商標)は、まったく同じ感覚ではないか、ジョブの実際のコードを比較するなど、他の言語に良い参照の本質の理解に加え、参照を感じることができません。

ここでは単にアセンブリコード内の参照とポインタの違いを比較します:

コンパイラ:GCC 9.3 x86-64の
C ++標準:-std = C ++ 17
の任意の最適化なし

オンラインコンパイラURLます。https://godbolt.org/


比較:int型&とint型* constの二種類の
理由はここに通常のポインタを選択するための通常のポインタが、それは変更することはできませんので、どこ使用のconstポインタ自体、宣言時に狭め2間の最小のギャップのために、初期化することはできませんではありませんそのシニフィアンを変更。

1 引数として渡される。
 ボイド pointer_const(INT * CONST );
 ボイドリファレンス(INT); 
両方の一貫した生成アセンブリコードは、次の
        プッシュRBP 
        MOV RBP、RSP                // 関数プッシュ 
        MOV QWORD PTR [RBP- 8。 ] 、RDI // 渡すパラメータ
        NOP 
        POP RBP 
        RET                             // 戻り
        
2 。オブジェクトが初期化され、操作を
 INT C = 100 ;             // .LONG 100
 // グローバル初期化
INTを* のConst PTR =&C;    // コードを生成しない
INTREF = Cを;             // .quad C 

ボイド試験(){
     // 内部初期化関数の値
    INT * CONST PTr1は=&C; //          MOV QWORD PTR [RBP- 8]、OFFSET FLAT:C 
    INT&REF1 = C;       //                MOV QWORD PTR [RBP-16]、OFFSET FLAT:Cは、
     // 上記の両方の目に見えるが、アセンブリコードと同じである
    
    。// 同じタイプの変数の初期化
    INT * constの PTR2 = PTR;                
     int型&REF2 = REF//                  、変更されていない上記のコード

    REF ++; //         MOV EAX、OFFSET FLAT:C
            //          MOV EDX、PTR DWORD [RAX]
            //           追加EDX ,. 1
            @         MOV DWORD PTR [RAX]、EDX 
 * PTR )++; //         MOV EAX、PTR DWORD C [RIP]
               //         追加EAX ,. 1
               @         MOV DWORD PTR C [RIP]、EAX 
              
    // 操作に見える参照ポインタの相対的な多工程である
    
    // 新規作成変数
    INT Y * = PTR;
         //     MOV EAX、PTR DWORD C [RIP]
         //    DWORD PTR MOV [-RBP 4]、EAX 
    INT X = REF ;
             // MOV EAX、OFFSET FLAT:C
             // MOV EAX、DWORD PTR [RAX]
             // MOV DWORD PTR [-RBP 8]、EAX
     // 可視参照又は多段階の操作が
} 


// 次はCローカル変数と同じ動作となるであろう

ボイド試験(){
     int型 C = 100 ;              //          MOV DWORD PTR [RBP-68]、100 
    
    INT * CONST PTR =&C ;    //          LEA RAX、[RBP-68]
                             //            MOV QWORD PTR [-RBP 8]、RAX
                            
    INTREF = C;             //         同じポインタ

    INT * CONST PTR2 = PTR; //   上記
    INT&REF2 = REF ;         //   上記

    INT XX = REF ;
     INT YY * = PTR;
     //          MOV RAX、QWORD PTR [RBP- 16]
     //          MOV EAX、DWORD PTR [RAX]
     //          MOV DWORD PTR [RBP-20である]、EAX
     // コードのみが置かれている同じ、
    
    
    int型 Y * = PTR;
     INT X = REF ;
     //        RAXのMOV、QWORD PTR [RBP-8]
     //         MOV EAX、DWORD PTR [RAX]
     //         MOV DWORD PTR [RBP-28]、EAX
     //      同様に、ちょうどここのコードの一部を置く
    
    // 見えるの両方と何も違い
} 

// 我々はポインタ参照を入れて、動作パラメータの関数でそのなった場合

のボイドテスト(int型&X、int型 * constのPTR){ 
    X ++ ;  * PTR)++ ;
     / *   //コードのみ置くとして
        MOV RAXを、QWORD PTR [-RBP。8] 
        MOV EAX、DWORD PTR [RAX] 
        LEA EDX、[RAX + 1] 
        MOV RAX、QWORD PTR [-RBP。8]
        DWORD PTR MOV [RAX]、EDXは
    * / 
}

// クラスTestを用いて上記のように我々が行った場合:

INT C = 100 ; //          .LONG 100 

クラスA { 

    静的 INT * CONSTのstatic_const_ptr、
     静的 INTstatic_reference; 
    
    INT * constのPTR;
     INTREF ; 

    公共
        A(INT PTR *、INTREF):PTR(PTR)、REFREF ){}
         ボイドtest_ptr();
        test_ref();
        静的 無効test_static_ptr();
        静的 無効test_static_ref(); 
}。

int型 * constの A :: static_const_ptr =&C; //          .quad C 
のint&A :: static_reference = C;         //          .quad C 

のボイドA :: test_ptr(){  * PTR)++ ;
    / * 
    A :: test_ptr():
        プッシュRBP 
        MOV RBP、RSP 
        MOV QWORD PTR [RBP-8]、RDI 
        MOV RAX、QWORD PTR [RBP-8] 
        MOV RAX、QWORD PTR [RAX] 
        MOV EDX、DWORD PTR [RAX] 
        EDXを追加し、1
        DWORD PTR MOV [RAX]、EDX 
        NOP 
        POP RBP 
        RET 
    * / 
} 

ボイドA :: test_ref(){
     REF ++ ;
     / * 
    A :: test_ref():
        プッシュRBP 
        MOV RBP、RSP 
        MOV QWORD PTR [-RBP 8] 、RDI 
        MOV RAX、QWORD PTR [-RBP。8] //数値が変化する位置番号2つのメンバ変数を変更、問題に対処している
        MOV RAXを、QWORD PTR [RAX +。8] 
        MOV EDX、PTR DWORD [RAX] 
        EDX追加,. 1 
        MOV DWORD PTR [RAX]、EDX 
        NOP 
        POP RBP 
        RET 
    * /
    
} 
// 可见并无什么区别


空隙A :: test_static_ptr(){  * static_const_ptr)++ ;
    / * 
    A :: test_static_ptr():
        プッシュRBPの
        MOVのRBP、RSP 
        MOV EAX、DWORD PTRのC [RIP] 
        追加EAX、1つの
        MOV DWORD PTRのC [RIP]、EAX 
        NOP 
        ポップRBP 
        RET 
    * / 
} 

ボイドA :: test_static_ref( ){ 
    static_reference ++ / * 
    A :: test_static_ref():
        プッシュRBP 
        MOV RBP、RSP 
        MOV EAX、FLATをOFFSET:C 
        MOV EDX、DWORD PTR [RAX] 
        EDXを追加し、1 
        MOV DWORD PTR [RAX]、EDX 
        NOP 
        POP RBP 
        RET 
    * / 
} 

// 可視及びEAX MOVオフセットFLAT限りステップ動作の前に:C 


// 我々は構造Cにint型であろう、その構造が複雑であり、次の通り:

構造体A {
     int型のX、Y; 
}; 


ボイド試験(A * CONST PTR、A&REF ){
     //         プッシュRBP
     //           MOV RBP、RSPプッシュ
     //         MOV QWORD PTR [ RBP-8]、RDI可視PTR [RBP-8] PTRある
     //          MOV QWORD PTR [RBP-16] 、RSI 可視PTR [RBP-16] REFで
    
    
    PTR  - > X =0 ; //    MOV RAX、QWORD PTR MOV DWORD PTR [RAX]、0 [-RBP 8]      
    REF .X = 0 ;   //    RAX MOV、QWORD PTR [RBP-16] MOV DWORD PTR [RAX]、0 
    
    PTR - > Y = 0 ; //    MOV RAX、QWORD PTR [-RBP 8] MOV DWORD PTR [RAX + 4]、0 
    REF .Y = 0 ;   //    MOV RAX、QWORD PTR [RBP-16] MOV DWORD PTR [RAX + 4]、0 
    
    
    / * リターン
        NOP 
        POP RBP 
        RETは
        差異は認められませんでした
    * / 
}

要約:Cをコードはそう:主な違いは、複数のMOV EAXとなるオブジェクト参照静的変数またはクラスグローバル動作時に、FLATをオフセットすることです

 

おすすめ

転載: www.cnblogs.com/MasterYan576356467/p/12657155.html