回覆列表
  • 1 # IT劉小虎

    前兩天,我在我的圈子裡發了一個小問題,剛好和題主的問題很吻合,相關的C語言程式碼如下,這段程式會輸出什麼呢?

    題外話

    在分析這個問題之前,先說些題外話。有程式設計師認為研究這樣的程式碼沒有意義,無異於孔乙己的“茴”字有幾種寫法。

    這個問題其實並不是我空想出來的。

    最近,我的一個同事被他的C語言程式 bug 困擾了好幾天,始終無法找到問題究竟出在哪裡,於是找我,我看到他的程式碼居然混用無符號變數和有符號變數,於是就提醒他注意這個方面,後來發現果然是這個原因。他的問題涉及到比較複雜的專案,完整的複述一遍不太現實,於是我把他的問題精簡一下,就構成了上述C語言程式碼段。

    事實上,很多公司招聘時,都有一些面試題或者筆試題看起來很怪異,很不符合標準的開發規範,於是有些程式設計師就認為做這樣的面試題是完全沒有意義的,甚至覺得做這些題目是一種侮辱。

    其實換個角度想想,這些題目很能考察一個人的基本功,它們很可能來自公司內部的某個專案的某次重大 bug。C語言是一門極其重視基本功的程式語言,這些題目很能查漏補缺。

    分析

    現在來考慮上面這段C語言程式碼,我們編譯並執行它,得到了下面的輸出:

    C語言程式的輸出出乎了一些朋友的預料,-1 容易理解,255 是怎麼回事呢?

    首先要明白的是,在計算機中,整數通常採取補碼的形式儲存。負數的補碼等於其反碼+1,負數的反碼符號位不變,數值為按位取反。對於 signed char 型變數,大部分C語言編譯器都是由 8 個 bit 組成的,最高一個 bit 通常表示符號位。

    所以對於 -1,其原碼原本是 0b10000001,但是計算機內部儲存該數值時,是以補碼形式儲存的。-1 的補碼等於反碼+1,也即 0b11111110 +1 = 0b11111111 = 0xff。

    到這裡就清楚了,變數 b 在記憶體裡的 8 個 bit 都是 1,它是一個 unsigned char 型的變數,最高 bit 也表示數值,也即 b 等於 255。

    現在再來分析變數 c 和變數 d 的值,它倆都是有符號型的 int 型。按理說,a 和 b 在記憶體中的佈局是一樣的,都是 8 個 bit 的 1,為什麼傳遞給 c 和 d 就不一樣了呢?

    其實C語言在處理 c = a; 和 d = b; 這兩句賦值語句時,有一個過程沒有顯式的表現出來,即“整形提升”。以 c=a; 為例,因為 c 和 a 的資料型別不同,所以C語言在處理賦值時,為了不丟失精度,會將 a 中的數值也強制轉換為 int 型。

    a 中的數值是 -1,提升為 int 型後依然是 -1,而不是 0x000000ff(255,這裡假設 int 型別佔用 4 位元組記憶體空間)。至於變數 d 的值,就更簡單了,就是簡單的賦值而已。

  • 中秋節和大豐收的關聯?
  • 馬德里西班牙國家考古博物館值得去嗎?