[英]Why doesn't CHAR_MAX + 1 cause overflow?
K&R的C編程語言中進行了一項練習,以查找各種類型(例如char和int)的最大值/最小值。
在下面的代碼中:
#include<stdio.h>
#include<limits.h>
void main()
{
printf("Size of Char Max %d\n", CHAR_MAX);
printf("Max Char+1 = %d\n",CHAR_MAX+1); //my test code
}
由於CHAR_MAX
為127(這是char
類型的最大值),為什么不加1導致溢出?
首先, char
的范圍是-128到127還是0到255或完全由實現定義。 該標准沒有定義char
是帶signed
還是unsigned
,也沒有定義必須具有8個二進制位,盡管在實踐中可以安全地假定使用后者。 參見ISO / IEC 9899:1999中的3.9.1(1):
(...)由實現定義,
char
對象是否可以容納負值。 (...)
唯一的保證是CHAR_MIN
不大於0, CHAR_MAX
不小於127(在附件E中)。
至於添加,您不會溢出,因為CHAR_MAX
和1
(以及11
)都是int
,而不是char
,因此不會發生溢出。
而且,即使加上
char c = '\x7f';
c + c;
(即char + char
)的類型為int
,即使對char
進行了signed
也不會溢出,因為通常的算術轉換適用於+
的操作數。 簡而言之,這些狀態表示在算術運算中,所有操作數都將轉換為最大涉及的類型,並且整數提升適用於整數類型。 整數提升表示,在應用它們時,小於int
整數類型將轉換為至少int
,因此我們再次具有int + int
且沒有溢出。
關於第一段中“八位二進制位”說明的附錄/附帶說明:從歷史的角度來看,問題超出了二進制計算機上數據類型的位數。 今天它沒有什么實際意義,但是C並非在所有普通計算機都使用整數的二進制補碼表示的時候編寫的。 因此,附件E中為有符號類型給出的實現限制是對稱的(例如INT_MAX <= 32767
和INT_MIN >= -32767
而不是-32768)。 在使用補碼或有符號幅度表示的機器上,我們習慣於不存在的非對稱性根本不存在,並且有兩個零值(0和-0)。
您正在以整數類型(%d)打印CHAR_MAX
的值。 因此它將按整數數據類型打印該值。
char
總范圍是-128 to 127
。
對於整數是四個字節。 因此沒有溢出。
你可以試試看
char a=256;
這樣分配時,您會得到警告。
warning: overflow in implicit constant conversion [-Woverflow]
CHAR_MAX
in被定義為宏常量,而不像您想的那樣屬於char
類型。 在這里看看。
在printf("Max Char+1 = %d\\n",CHAR_MAX+1);
,預處理器將CHAR_MAX
替換為127
。 由於127 + 1為128,並且格式說明符為%d
(int),因此沒有溢出。
您的想法對此是正確的:
printf("Max Char+1 = %d\n",(char)(CHAR_MAX+1));
讓我們回顧一下這行代碼:
CHAR_MAX+1
的int
值等於0x00000080(128) char
,將被截斷為char
值0x80(-128) printf
,它將擴展為int
值0xFFFFFF80(-128) 由於您沒有在代碼中將其int
為char
,因此int
值0x00000080將“按原樣”傳遞給printf
。
上面的答案是基於您平台上的CHAR_BIT
為8且sizeof(int)
為4的假設。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.