在計算機中,資料在記憶體中以二進位制形式儲存,負數有三種表示方法:原碼,反碼,補碼。任何正數的原碼,反碼,補碼的形式均相同,而負數有不同的表現形式。
資料在計算機中大都以二進位制補碼形式儲存,原因是:
數的原碼表示形式簡單,適用於乘除運算,但用原碼表示的數進行加減運算比較複雜;引入補碼之後,減法運算也可以用加法來實現,且數的符號位也可以當作數值一樣參加運算,並且其他運算均是以假髮為基礎進行運算的;因此在計算機中大都採用補碼來進行運算。
好了,廢話扯完了!
在c語言中,我們對資料的使用時要注意一些問題:
資料溢位:每種資料型別都有一定的範圍,不當使用造成資料溢位會造成不可預知的錯誤:
隱式型別轉換:不同型別資料在賦值時,如未進行顯示轉換,編譯器會自己進行隱式型別轉——其中會從涉及到資料截斷和整型提公升以及符號位擴充
int
main()
你是怎麼思考的呢?%u列印時思考起來是不是有點困難?那我們先來看看%d列印,都知道%d是按有符號整數型別列印的,那結果就是:-128 128 了,對不對?
那以%u列印的結果是多少呢?我們執行起來看看結果:
這裡我們發現:
a和b無論是以何種方式列印的列印結果均相同
以%d形式列印128竟然列印出的結果為-128
以%u形式列印a和b竟然都是兩個很大的數
怎麼會這樣?是編譯器有問題嗎?很明顯不是的!
那麼我來解釋一下,首先char型別的資料是有範圍的,其資料型別的範圍為:-128~127,那麼當給b賦值128時發生了什麼?很明顯是資料溢位了,那溢位導致的結果呢?我們來看一下給b複製後b在記憶體中的儲存形式:
可以看到b在記憶體的存放形式為十六進製制的80,那麼0x80是如何來的呢?我是這樣理解的:
128=127+1
127為正數,原,反,補碼相同為:0111 1111
同理1的補碼:0000 0001
兩者相加導致資料溢位使得進製佔據了符號位得:1000 0000即為128在記憶體中的存放形式0x80
同時我還發現-128在記憶體中的儲存形式為0x80,這裡就讓我很不解了,0x80按照負數的原碼補碼關係得0x80的原碼形式的十進位制數為-0啊,不應該是-128啊!這時怎麼回事?
簡單來說,我的理解就是-0是沒有意義的,因此就用0x80作為-128的補碼形式,而且-128可以理解為-127-1即(-127+(-1));
當然這裡有大佬比我解釋的更具體:原**為什麼char型別的範圍是 —128~+127,在此膜拜一下,以表敬意!
理解了這些,就對這段**的執行結果理解一半了,那麼另一半呢?就是%u輸出了,很簡單,當以%u形式輸出時需要對變數擴充為unsigned int型別,a,b在記憶體中都是0x80,編譯器識別為負數即擴充時高位和符號位保持一致,即就是進行了隱式型別轉換,a,b擴充的結果為0xff ff ff 80,其轉換成十進位制為:4294967168
這樣這道題就說得通了!
謝謝觀閱,如有問題,還請不吝賜教!
隱式型別轉換
c 本身對內建型別定義了各種隱式的型別轉換,這種內建的型別轉換在可能導致精度 丟失的情況下編譯器會發出警告,但當我們定義自己的型別時,提供各種隱式轉換往往 是弊大於利的 至少在我編寫過的 中很少用到 隱式的型別轉換可分為 其它型別到本型別,本型別到其它型別兩種.第一種通過單變數 可呼叫之建構函式進行...
隱式型別轉換
c語言中有以下四種情況會進行隱式轉換 1 算術運算子中,低型別轉換為高型別。2 賦值表示式中,右邊表示式的值自動隱式轉換為左邊變數的型別,並賦值。3 函式呼叫傳遞引數時,系統將實參轉換為形參的型別後,賦給形參。4 函式有返回值是,系統將表達值型別轉換為返回值型別。進行算術運算時,不同型別的數必須轉換...
隱式型別轉換
1.c的整型算數運算總是至少以預設型型別的精度來進行的。為了獲得這個精度,表示式的字元和短整型運算元在使用之前被轉換為普通整型,這種轉換叫 整型提公升 下面我們來看個例子 char a 2 char b 127 char c a b 求c 多少?首先char為1個位元組 而且是有符號的 char最大...