今天咱們由C語言的一個經典題目入手,跟你們聊聊C語言一個很是重要的規則,不要着急,讓咱們從-1大於1的例子提及。ios
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了。spa
由-1大於1的例子,咱們對C語言的自動轉換原則進行簡單總結。3d
通常來講,C語言存在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」
編程學習書籍:
編程學習視頻: