上面將生成一條讀取內存的語句,即使從內存中讀出來的數字沒有任何應用(當然,假如編譯器開了優化選項,則上面的語句將不會生成任何代碼)。從這一點以及上面的c = a / b * 120.4f;語句中,都可以看出一點——變量是可以返回數字的而變量返回的數字就是按照變量的類型來解釋變量對應內存中的內容所得到的數字。這句話也許不是那么輕易理解,在看過后面的類型轉換一節后應該就可以理解了。
因此為了將數據寫入一塊內存,使用賦值語句(即等號);要讀取一塊內存,書寫標識內存的變量名。所以就可以這樣書寫:a = a + 3;
而如上的float a;語句,當還未對變量進行任何賦值操作時,a的值是什么?上帝才知道。當時的a的內容是什么(對于VC編譯器,在開啟了調試選項時,將會用0xCCCCCCCC填充這些未初始化內存),就用IEEE的real*4格式來解釋它并得到相應的一個數字,也就是a的值。因此應在變量定義的時候就進行賦值(但是會有性能上的影響,不過很?。?,以初始化變量而防止出現莫名其妙的值,如:float a = 0.0f;。
賦值操作符
上面的a = a + 3;的意思就是讓a的值增加3。在C++中,對于這種情況給出了一種簡寫方案,即前面的語句可以寫成:a += 3;。應當注重這兩條語句從邏輯上講都是使變量a的值增3,但是它們實際是有區別的,后者可以被編譯成優化的代碼,因為其意思是使某一塊內存的值增加一定數量,而前者是將一個數字寫入到某塊內存中。所以假如可能,應盡量使用后者,即a += 3;。這種語句可以讓編譯器進行一定的優化(但由于現在的編譯器都非常智能,能夠發現a = a + 3;是對一塊內存的增值操作而不是一塊內存的賦值操作,因此上面兩條語句實際上可以認為完全相同,僅僅只具有簡寫的功能了)。
對于上面的情況,也可以應用在減法、乘法等二元非邏輯操作符(不是邏輯值操作符,即不能a &&= 3;)上,如:a *= 3; a -= 4; a = 34; a >>= 3;等。
除了上面的簡寫外,C++還提供了一種簡寫方式,即a++;,其邏輯上等同于a += 1;。同上,在電腦編程中,加一和減一是經常用到的,因此CPU專門提供了兩條指令來進行加一和減一操作(轉成匯編語言就是Inc和Dec),但速度比直接通過加法或減法指令來執行要快得多。為此C++中也就提供了“++”和“—”操作符來對應Inc和Dec。所以a++;雖然邏輯上和a = a + 1;等效,實際由于編譯器可能做出的優化處理而不同,但還是如上,由于編譯器的智能化,其是有可能看出a = a + 1;可以編譯成Inc指令進而即使沒有使用a++;卻也依然可以得到優化的代碼,這樣a++;將只剩下簡寫的意義而已。
注重前面之所以會朝好的方向發展(即char轉成float),完全是因為“==”的緣故,其要求這么做。下面考慮“=”:short b = 3543; char a = b;。因為b的值是short類型,而“=”的要求就是一定要將“=”右邊的數字轉成和左邊一樣,這樣才能進行正確的內存的寫入(簡單地將右邊數字返回的二進制數復制到左邊的地址所表示的內存中)。因此a將為-41。但是上面是編譯器按照“=”的要求自行進行了隱式轉換,可能是由于程序員的疏忽而沒有發現這個錯誤(以為b的值一定在-128到127的范圍內),因此編譯器將對上面的情況給出一個警告,說b的值可能被截斷。為了消除編譯器的疑慮,如下:char a = ( char )b;。這樣稱為顯示類型轉換,其告訴編譯器——“我知道可能發生數據截斷,但是我保證不會截斷”。因此編譯器將不再發出警告。但是如下:char a = ( char )3543;,由于編譯器可以肯定3543一定會被截斷而導致錯誤的返回值,因此編譯器將給出警告,說明3543將被截斷,而不管前面的類型轉換操作符是否存在。
現在應該可以推出——15 + 15.0f;返回的是一個float類型的數字。因此假如如下:char a = 15 + 15.0f;,編譯器將發出警告,說數據可能被截斷。因此改成如下:char a = ( char )15 + 15.0f;,但類型轉換操作符“()”的優先級比“+”高,結果就是15先被轉換為char然后再由于“+”的要求而被隱式轉成float,最后返回float給“=”而導致編譯器依舊發出警告。為此,就需要提高“+”的優先級,如下:char a = ( char )( 15 + 15.0f );就沒事了(或char( 15 + 15.0f )),其表示我保證15 + 15.0f不會導致數據截斷。