首先是一道關於類型轉換的面試題,要求給出float變量強制轉換成int型和int &輸出的結果。
[cpp] int test()
{
float a = 1.0f;
cout<<"value of (int)a is "<<(int)a<<endl;
cout<<"value of &a is "<<&a<<endl;
cout<<"value of (int &)a is "<<(int &)a<<endl;
cout<<boolalpha<<((int)a == (int &)a)<<endl;
return 0;
}
int test()
{
float a = 1.0f;
cout<<"value of (int)a is "<<(int)a<<endl;
cout<<"value of &a is "<<&a<<endl;
cout<<"value of (int &)a is "<<(int &)a<<endl;
cout<<boolalpha<<((int)a == (int &)a)<<endl;
return 0;
}
以前編程經常用到強制轉換(int)variable,對於上例,就是把float型的值1.0作為int型輸出1,但是如何理解(int &)variable,為什麼輸出會是一個大整數1065353216呢?這裡需要區分&的兩個作用:取地址和引用。以下是參考CSDN論壇的詳細解釋。
(int)a實際上是以浮點數a為參數構造了一個整型數,該整數的值是1,(int&)a則是告訴編譯器將a當作整數看(並沒有做任何實質上的轉換)。因為1以整數形式存放和以浮點形式存放其內存數據是不一樣的,因此兩者不等。對float b = 0.0f;的兩種轉換意義同上,但是0的整數形式和浮點形式其內存數據是一樣的,因此在這種特殊情形下,兩者相等(僅僅在數值意義上)。
注意,程序的輸出會顯示 (int&)a=1065353216,這個值是怎麼來的呢?前面已經說了,1以浮點數形式存放在內存中,按ieee754規定,其內容為0x0000803F(已考慮字節反序)。這也就是a這個變量所占據的內存單元的值。當(int&)a出現時,它相當於告訴它的上下文:“把這塊地址當做整數看待!不要管它原來是什麼。”這樣,內容0x0000803F按整數解釋,其值正好就是1065353216(十進制數)。
通過查看匯編代碼可以證實“(int)a相當於重新構造了一個值等於a的整型數”之說,而(int&)的作用則僅僅是表達了一個類型信息,意義在於為cout<<及==選擇正確的重載版本。
我們再看變量中使用指針*和引用&的例子,&作為引用主要是用在變量的聲明,也就是將此變量作為一個別名,兩變量內存地址完全相同。下面是對int *a, int &b, int * &c, int & *d的實驗和簡單說明。
[cpp] int test()
{
int i = 10;
int *a = &i; /* a是一個指針,指向i的地址, &取地址 */
cout<<"value of a is "<<a<<endl; /* i的地址 */
int &b = i; /* b是引用,和i指向同一地址,可視為i的別名 */
cout<<"value of b is "<<b<<endl; /* i的內容,10 */
cout<<"value of &b is "<<&b<<endl; /* i的地址 */
int * &c = a; /* c是引用,引用的類型是指針(和a相同) */
cout<<"value of c is "<<c<<endl; /* c是a的別名 */
/* int & *d = b; d是一個指針,但引用不是實體,所以是錯誤的 */
return 0;
}