2017-03-16 111 views
0
#include<stdio.h> 
int main() 
{ 

    char c =118,a=117; 
    c=c+10; 
    a=a+10; 
    printf("c:%d, a:%d\n", c,a); 

} 

答案是c:-128,a:127。在c中添加char值

有人可以解釋我爲什麼C + 10是-128和A + 10是127?

在此先感謝。

+0

@deepak請參見[默認情況下是char簽名還是未簽名?](http://stackoverflow.com/questions/2054939/is-char-signed-or-unsigned-by-default) 。你得到的結果是編譯器特定的。 – Lundin

+0

@Lundin:我的不好。除非'char'具有與'int'相同的位數,否則它確實是實現定義的。 – Olaf

+0

在你的系統上,很明顯'char'實際上是'signed char' – user3629249

回答

1

因爲char在你的編譯器中是8位的。所以118+10超出範圍(最大爲127)。

編譯器的實現將其「包裝」了一遍,而代之以-128

+0

這是未定義的行爲。任何結果都是正確的。 – Olaf

+1

好吧,未定義但實現定義:編譯器做了一些事情。可以截斷或換行。這就是爲什麼我在回答中非常謹慎,提醒它已經定義了實現(因此不可移植,非常接近未定義的行爲) –

1

在你的情況下,char是由編譯器的特定平臺上表示爲符號的8位值,並在2's complement reoresentation。這意味着最高位是符號位(如果它是1,則數字爲負數)。因此,非負值的二進制範圍是(二進制)00000000-01111111,它是十進制的0-127。負值範圍(以二進制形式)從10000000到11111111,十進制爲-128到-1。

如果你開始與118,在二進制這就是:

01110110 

如果我添加小數10,那就是把1010二進制:

01110110 
+00001010 
--------- 
10000000 

你可以看到現在的最高位,意味着數字溢出(變成大於十進制的最大值127),現在代表負數。 8位二進制值10000000恰好表示十進制的-128。

因此,將(以十進制)10加到char的值118中,得到-128。

a的值是117,所以10 + 117 = 127仍然適合7位,正值爲127.您可以將上述二進制分析作爲練習來了解它是如何工作的。

+0

這與UB無關。問題是,它不是UB,而是實現定義,我錯了 - 除非'char'具有與'int'相同的位數 - 不太可能。它必須在編譯器的文檔中指定。 – Olaf

+0

@Olaf是的,我同意。我更新了我的答案,以便更清楚地瞭解平臺和編譯器的依賴性。 – lurker

2

有符號的8位值範圍從-128到127. 127的位是0111 1111,而128位的位是1000 0000.問題是,在有符號數中,高位(最左邊)位是符號標誌(0是+,1是 - )。所以,因爲它是有符號的,所以計算機將其解釋爲一個負數,結果爲-128(如果我沒有記錯的話,這稱爲有符號溢出,並且在編程時每個人都會遇到這個問題)(檢查2的補碼看看爲什麼低7位是128,而不是0)。你可以通過聲明c和a來解決這個「問題」,而不是而不是char

順便說一句,可以保存一個變量是這樣的:

char a=117; printf("c:%d, a:%d\n", a+11,a+10);

+1

@Olaf,你能記下什麼,確切地說,是未定義的行爲?我的解釋回答了OP中實際發生的事情,而不是試圖確定應該發生什麼。 – andrew

2

117 + 10 = 127,其是在char類型的範圍(-128-127)

如果打開在程序員模式下你的窗口計算器,你可以看到118代表1110110二進制。另外,10表示爲1010.如果我們添加這兩個,結果是10000000。它不在char類型的範圍內,這個數字相當於-128。所以-128打印