[英]char data type is not giving negative numbers by adding a positive number to the character which is holding maximum positive value
我正在嘗試將“1”添加到一個持有它可以持有的最大正值的角色。 它給出 0 作為 output 而不是給出 -256。
#include <stdio.h>
int main() {
signed char c = 255;
printf("%d\n", c + 1 );
}
O / P : 0
c + 2 = 1;
c + 3 = 2;
根據我的理解,一旦達到最大限制(),它應該給出負數。 這個對嗎? 我正在測試 Ubuntu。
有signed char
通常是 8 位編碼值 [-128...127]。
signed char c = 255;
正在嘗試將c
初始化為有signed char
范圍之外的值。
接下來發生的是實現行為。 非常常見的是255
將“mod” 256 轉換為 -1 的值。
signed char c = 255;
printf("%d\n", c ); // -1 expected
printf("%d\n", c + 1 ); // 0 expected
根據我的理解,一旦達到最大限制(),它應該給出負數。 這個對嗎?
不。在最大int
值上加 1 是未定義的行為。 沒有應該。 它可能會導致負數,可能不會,可能會退出代碼 - 它沒有定義。
如果代碼是
signed char c = 127;
printf("%d\n", c + 1 );
c + 1
將是 128 並且"128\n"
將被打印為c + 1
是一個int
操作,其范圍內為int
sum。
這里有幾個隱式轉換需要跟蹤:
signed char c = 255;
是將int
類型的常量255
轉換為更小的有signed char
。 這是“通過賦值進行左值轉換”(初始化遵循賦值規則),其中右操作數被轉換為左操作數的類型。
從大符號類型到小符號類型的實際轉換遵循以下規則:
否則,新類型是有符號的,值不能在其中表示; 結果是實現定義的,或者引發了實現定義的信號。
實際上,在二進制補碼計算機上很可能發生的轉換是您最終得到的有符號字符的十進制值等於0xFF
,即-1
。
c + 1
是一個操作數分別為signed char
和int
類型的操作。 對於 + 運算符,這意味着執行通常的算術轉換,請參閱隱式類型提升規則。
含義c
被轉換為int
並且對int
類型進行操作,這也是結果的類型。
printf("%d\n", stuff );
像printf
這樣的函數接受可變數量的 arguments 會經歷一個奇怪的轉換規則,稱為默認參數Promotions 。 如果是整數,則表示執行了 integer 促銷活動(參見上面的鏈接)。 如果您將c + 1
作為參數傳遞,則類型為int
並且不會發生提升。 但是,如果您剛剛通過c
,那么根據這些規則,它會被隱式提升為int
。 這就是為什么將%d
與字符類型一起使用實際上有效的原因,即使它是用於打印字符的錯誤轉換說明符。
根據我的理解,一旦達到最大限制(),它應該給出負數。 這個對嗎?
如果你只是簡單地做signed char c = 127; c++;
signed char c = 127; c++;
那么這是一個有符號的溢出,未定義的行為,沒有可預測的結果。
如果你signed char c = 127; ... c + 1
signed char c = 127; ... c + 1
因為隱式提升到int
,所以沒有溢出。
如果你做unsigned char c = 255; c++;
unsigned char c = 255; c++;
然后有一個明確定義的環繞,因為這是一個無符號類型。 c
將變為零。 有符號類型沒有這樣一個定義良好的環繞——它們會溢出。
在實踐中,有符號數溢出是 C 標准發明的人為胡說八道。 當您在匯編程序級別發生溢出時,所有知名計算機都會設置一個溢出和/或進位位,並由核心手冊正確記錄和明確定義。 它在 C 中變成“未定義行為”的原因主要是因為 C 允許無意義的符號格式,例如一個人的補碼或有符號幅度,可能具有填充位、陷阱表示或其他此類奇異的、主要是虛構的東西。
盡管如今,優化編譯器利用不允許發生溢出的優勢,以生成更高效的代碼。 這是不幸的,因為如果 2 的補碼是唯一允許的格式,我們可以同時擁有快速和 100% 確定性代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.