c++の参照の本質
参照変数はc++導入の重要なメカニズムである.
誤った観念:引用の本質は別名にすぎず、シンボルテーブルのriとiは同じ変数アドレスに対応する
下位実装では、参照はポインタ定数で実装され、ポインタ定数で実装されると、逆アセンブリは毛のようになります.参照とポインタの定数の関係は次のとおりです.
(1)メモリ占有量はいずれも4バイトであり,格納はすべて参照対象のアドレスであり,定義と同時に初期化しなければならない.
(2)ポインタ定数自体がアドレスを許可する.参照変数はアドレス指定を許さず、&rは参照対象のアドレスを返し、変数rのアドレスではなく変数rの値であり、rのアドレスはコンパイラによって把握され、プログラム猿は直接アクセスできない.
(3)参照するコードは、ポインタ定数で実現することができる.逆に、参照自体の制限が多いため、ポインタのすべての操作を完了することはできません.
たとえば、次のコードは正当です.
しかし、次のコードは不正です.
参照は初期化時に変数をバインドしますが、参照バインド関係を変更する特別な手段もあります.
答えの出力:
&i == 003CF9D0 &j == 003CF9C4 &pi == 003CF9AC &pj == 003CF9A0 dis == -12 3996112 3996100 i == 5 j == 666
メモリに配置する方法は次のとおりです.
dis低アドレスaddr pj pi r j i高アドレス
&j==003 CF 9 C 4&pi==003 CF 9 ACで2つのdisを隔てて、実は1つのrを挟んだのです
誤った観念:引用の本質は別名にすぎず、シンボルテーブルのriとiは同じ変数アドレスに対応する
int i=5;
0100437E mov dword ptr [i],5
int &ri=i;
01004385 lea eax,[i]
01004388 mov dword ptr [ri],eax
ri=8;
0100438B mov eax,dword ptr [ri]
ri=8;
0100438E mov dword ptr [eax],8
下位実装では、参照はポインタ定数で実装され、ポインタ定数で実装されると、逆アセンブリは毛のようになります.参照とポインタの定数の関係は次のとおりです.
(1)メモリ占有量はいずれも4バイトであり,格納はすべて参照対象のアドレスであり,定義と同時に初期化しなければならない.
(2)ポインタ定数自体がアドレスを許可する.参照変数はアドレス指定を許さず、&rは参照対象のアドレスを返し、変数rのアドレスではなく変数rの値であり、rのアドレスはコンパイラによって把握され、プログラム猿は直接アクセスできない.
(3)参照するコードは、ポインタ定数で実現することができる.逆に、参照自体の制限が多いため、ポインタのすべての操作を完了することはできません.
たとえば、次のコードは正当です.
int i=5,j=6;
int *const array[] = {&i,&j}; //
しかし、次のコードは不正です.
int i=5,j=6;
int &array[] = {i,j}; //
参照は初期化時に変数をバインドしますが、参照バインド関係を変更する特別な手段もあります.
int main()
{
//freopen("input.txt","r",stdin);\
int i=5,j=6;
int &r = i;
void *pi = &i,*pj = &j;
int* addr;
int dis = (int)pj-(int)pi;
addr = (int *)((int)pj+dis); // r
cout<<"&i == "; PRINT(pi); //i
cout<<"&j == "; PRINT(pj); //j
cout<<"&pi == "; PRINT(&pi); //pi
cout<<"&pj == "; PRINT(&pj); //pj
cout<<"dis == "; PRINT(dis);
PRINT(*addr);
//(*add)+=dis;
(*addr)=(int)&j; PRINT(*addr); // r j
r=666;
cout<<"i == "; PRINT(i);
cout<<"j == "; PRINT(j);
return 0;
}
答えの出力:
&i == 003CF9D0 &j == 003CF9C4 &pi == 003CF9AC &pj == 003CF9A0 dis == -12 3996112 3996100 i == 5 j == 666
メモリに配置する方法は次のとおりです.
dis低アドレスaddr pj pi r j i高アドレス
&j==003 CF 9 C 4&pi==003 CF 9 ACで2つのdisを隔てて、実は1つのrを挟んだのです