為啥-1大於1,-1乘3卻不等於-3?直到了解C語言自動轉換原則後...
今天我們由C語言的一個經典題目入手,跟大家聊聊C語言一個非常重要的規則,不要著急,讓我們從-1大於1的例子說起。
unsigned int i=1;
signed int j=-1;
很簡單,無符號數i,有符號數j,比較i和j的大小,按照常理i是大於j的,但是實驗證明j>i,也就是說-1>1,為什麼會這樣呢?
其實出現這個情況的原因就是C語言中的自動轉換原則,這也是今天我們想給大家說的話題。在C語言中,若遇到無符號數和有符號數之間的操作,這時候會出現資料型別的提升現象,編譯器會自動把有符號數轉化為無符號數來進行處理,因此i是1沒錯,但j卻不是-1了,而是變成了 4294967295。所以j>i了。
關於資料為何是4294967295,我們今天從數學的角度給大家分析一下,供大家參考。
首先大家知道無符號數unsigned int的表示範圍是:[0 4294967295 ]= [0 2147483647] U [2147483648 4294967295],數學上稱為值域。而有符號數int的值域是 [-2147483648—2147483647]。兩個區間的元素個數都是4294967296個。
由此看出,二者的公共域是[0 2147483647],所以有符號數int的[-2147483648 -1] 對應 unsigned int的[2147483648 4294967295],這種一一對應的關係,數學上叫做對映。到這裡,資料的對應關係就一目瞭然了, -1 自然對應的就是 4294967295了。
由-1大於1的例子,我們對C語言的自動轉換原則進行簡單總結。
一般來說,C語言存在4種情況的自動轉換,也稱為隱式轉換。
1、算術運算式中,低階型別轉換為高階型別。(下面的圖對低階和高階進行了說明,大家可以參考)
2、賦值表示式中,右邊表示式的值自動隱式轉換為左邊變數的型別,並賦值給他。
3、函式呼叫中引數傳遞時,系統隱式地將實參轉換為形參的型別後,賦給形參。
4、函式有返回值時,系統將隱式地將返回表示式型別轉換為返回值型別,賦值給呼叫函式。
當然,以上情況只是進行了一般的總結,有些細節還沒有提到,比如字元必須先轉換為整數,short必須轉換為int,float型資料在運算時必須轉換為double來提高運算精度等等,有興趣的可以自行去了解學習。
瞭解自動轉換原則後,我們再來看這個微軟面試題
#include<iostream>
using namespace std;
int main(void)
{
unsigned int i=3;
cout<<i * -1;
return 0;
}
問結果會輸出什麼?有人說不是3而應該是12884901885,因為發生了隱式轉換。其實本題的答案是4294967293,哪裡有問題呢?我們一步一步分析,有符號數-1與無符號數3進行算數運算,-1變為無符號數4294967295,再乘3得12884901885。到這裡都沒問題,但是有一點很多人忽略了:那就是無符號數unsigned int只能表示32位,而此時的結果發生了溢位!因此結果是4294967293。
最後,關於本題這裡有一點,因為上述程式碼是C++,大家可以改寫成C語言,用printf來輸出,再看看執行結果,你會有新的發現哦!
好啦,就寫到這裡吧,希望今天的文章對大家的學習有所幫助。
最後,如果你也想成為程式設計師,想要快速掌握程式設計,趕緊加入學習企鵝圈子!
裡面有資深專業軟體開發工程師,線上解答你的所有疑惑~程式語言入門“so easy”
程式設計學習書籍:
程式設計學習視訊:
相關文章
- 在 javascript 中,為什麼 [1,2] + [3,4] 不等於 [1,2,3,4]?JavaScript
- C語言中的整數自動轉換原則C語言
- c語言運算過程中的型別自動轉換原則C語言型別
- c語言中資料型別的自動轉換原則C語言資料型別
- c語言中的資料型別的自動轉換原則C語言資料型別
- 基於 Alchemy 實現 AS3 與 C++ 互動(1)C++ 回傳 Array 給 AS3S3C++
- Used+Available不等於1K-blocksAIBloC
- PHP 轉換 SM2 加密資料 ASN1 編碼格式為 C1C3C2 格式資料PHP加密
- C++(1) gps轉換為enuC++
- 專案管理要遵守3C原則(轉)專案管理
- 標準C語言1C語言
- 高階C語言1C語言
- C語言實驗1C語言
- C語言作業1。C語言
- C語言---整型字串轉換C語言字串
- Foss Patents:高通1/3的收入來自於蘋果的專利費蘋果
- 為什麼 NaN 不等於自身?NaN
- C語言練習(3)——語句x=x&(x-1)的真實意義C語言
- C語言-1.簡介C語言
- 關於題目集1~3的總結
- C語言全面總結-3C語言
- 類似於C語言的printf函式 (轉)C語言函式
- 把字串(1,2,3,4,5)轉換為記憶體表形式字串記憶體
- c語言實現階乘C語言
- 關於函數語言程式設計的思考(1)函數程式設計
- 關於大數(C語言)C語言
- 關於C語言的常量C語言
- c語言字串,數字轉換C語言字串
- C 語言結構體的對齊原則結構體
- c語言資料結構補齊原則C語言資料結構
- [譯] [1] + [2] - [3] === 9!? 型別轉換深入研究型別
- C語言指標細節_1C語言指標
- C語言模擬試題1C語言
- C語言基礎-1、陣列C語言陣列
- C語言基礎-1、指標C語言指標
- unity3d 移動與旋轉 1Unity3D
- 轉換RM為MP3(轉)
- c語言基礎知識3C語言