這道C語言題有"圈套",基礎不好很容易上套!

1、

要看懂今天的代碼需要一點儲備知識。

這道C語言題有

2、

題目及分析

話不多說上代碼:

這道C語言題有

你算出的結果是什麼?

估計大部分的朋友算出的結果都是 2

這道C語言題有

初步分析

讓我們一起來看一下,大致分析這個代碼,可以發現這個代碼考察了兩個知識點:

一是數據類型轉換問題

二是運算符的優先級問題

這道C語言題有

上面這行代碼,~的優先級最高,首先肯定是對a進行按位取反,然後是+的優先級較高,所以執行4+1 =5,最後執行右移操作。

因此上面的代碼等價於:

這道C語言題有

也就是先對a進行逐位取反,~0xa5 = ~ (1010 0101b) = 0101 1010b = 0x5a

再右移5位得到0x2。結果算出來是2?

讓我們直接運行代碼來查看結果:

這道C語言題有

怎麼回事?答案並不是預期中的2,b忽然等於250!,這是為什麼呢?

這道C語言題有

隱式數據類型轉換和整值提升

這道C語言題有

讓我們再來仔細觀察上面這行代碼,發現出現了不同類型之間的運算:a的數據類型是char,4和1的數據類型沒有指定,c語言編譯器會默認其為int類型。

相信大家都知道,在C語言的運算過程中,如果運算符兩邊的數據類型不一致,編譯器會自動進行隱式數據類型轉換。

這種數據類型轉換總體來說比較複雜,但是總體遵循這個原則:儘量避免數據精度損失

上面的原則意味著什麼呢?

如果運算符兩邊的數據類型不一致,編譯器總是儘量往較寬的數據類型進行轉換。

如果計算過程中的計算數不是浮點數,那麼他們肯定都是整型,編譯器一般會將所有小於int類型寬度的數據類型提升到int,這種現象被稱為“整值提升


進一步分析

這道C語言題有

知道了整值提升,讓我們再來重新看看上面這行代碼:

a是unsigned char,數據寬度小於 int,所以編譯器在對a進行按位取反操作之前,會先將a的數據類型提升至int。

不同機器上,int的數據寬度不同,在我的機器上int的大小是4個字節。

因此將a進行數據類型轉換後,a = 0x 00 00 00 a5 ,按位取反以後就是 ~a = 0x ff ff ff 5a,然後再按位右移5位(高位自動補0),得到的就是0x07 ff ff fa ,在將該數值復給b的時候,因為b的數據類型是 char,只有一個字節,因此會發生數據截斷,只有最低位字節保留下來了,也就是 0xfa = 250。


總結

通過這道題,大家可以發現,如果對c語言的隱式數據類型轉換不熟悉,就很容易上套。

另外,運算符的優先級還是比較難記的,建議還是使用括號明確執行順序

對於熱愛編程的人來說,有一群一起學習一起解答的小夥伴很重要 !筆者有一個編程零基礎入門學習交流俱樂部()私信我【編程學習】進入,還有學習視頻文件,歡迎初學者和正在進階中的小夥伴們!


分享到:


相關文章: