VS2019中將十進位數賦值給char型輸出為末位數的原理是什麼?
char k=』123』;
輸出將為3
char m=』1290』
輸出將為0
char n=』1.7』
輸出將為7
經過多次嘗試後發現其輸出數字總為』』中數字的末位數,請問這是為什麼呢?
好像跟補碼和截斷都沒什麼關係,編譯器是怎麼處理的呢?
謝謝
你既然知道補碼和截斷,可能你都知道其原理了,就不多做介紹。
產生該結果的根本原因是:
char 為字元型,只能存儲朱ASCII中的字元,具體詳情,請訪問:
ASCII碼對照表?tool.oschina.net超出這個以外的,是不能進行存儲,所以也不能顯示。如果強制存儲,那麼就會產生截斷。和你的現象一樣,展示了末尾一位。
(上回是不是還看到過一個拿補碼和截斷的問為什麼不同的非零值都可以表示true...是題主嗎?
個人看法是被截斷了
關於這個單引號中存在多個字元的東西大概要翻譯成多字元字面量?是和雙引號下的字元串字面量完全區別開的概念,因為字元串最後一定有一個 而這個是沒有的。另一方面,這個東西其實雖然在C99被標準承認了,但是其實處於一個被認為可能會被濫用的尷尬的位置,大概可以類比一下goto吧。
所以這個多字元字面量表達的就是一個int長度的整數,在賦給一個低精度變數的時候被截斷了高位的部分。具體編譯器的操作細節大概可以看看圖吧,自己彙編學的幾斤幾兩還是知道的,就不獻醜了。算是拋磚引玉等一個更詳細的答案吧。
在最後補充一個自己剛剛現學現賣用的資料吧。這裡
直接上C90標準:6.1.3.4: 包含多於一個字元 ,或包含一個不在基本執行字符集中表示的字元或轉義序列的整型字元常量的值是實現定義的。
截最後一位是VS2019的實現。
問題有兩點:
1.『123』是字元常量,而不是數字。
2.運行環境:VS2019,在錯誤列表中,明顯有C4309(編譯器二級警告)截斷常量。
自低向頂,反彙編,從這一級來看的話,看到的也是截斷的。
mov byte ptr [c],63h
movsx eax,byte ptr [c]
push eax
push offset string "%s"
call _printf
進入寄存器的就是byte(c),壓棧,進行函數調用(printf)的還是 c。
我來回答。
單引號裡面是單個字元,雙引號里才是字元串。你寫的是單引號,只能有一個字元,編譯器自動給你取最後一個。
就這麼簡單。
題外話,python、js這些語言,單引號裡面也是字元串。
char k=』123』;
有引號就不是數字了啊。
數字賦值是char k=123
C++裡面 代表是字元。
相當於char k=3;
所以輸出3
推薦閱讀: