簡體   English   中英

為什么CHAR_MAX + 1不會引起溢出?

[英]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_MAX1 (以及11 )都是int ,而不是char ,因此不會發生溢出。

而且,即使加上

char c = '\x7f';

c + c;

(即char + char )的類型為int ,即使對char進行了signed也不會溢出,因為通常的算術轉換適用於+的操作數。 簡而言之,這些狀態表示在算術運算中,所有操作數都將轉換為最大涉及的類型,並且整數提升適用於整數類型。 整數提升表示,在應用它們時,小於int整數類型將轉換為至少int ,因此我們再次具有int + int且沒有溢出。

關於第一段中“八位二進制位”說明的附錄/附帶說明:從歷史的角度來看,問題超出了二進制計算機上數據類型的位數。 今天它沒有什么實際意義,但是C並非在所有普通計算機都使用整數的二進制補碼表示的時候編寫的。 因此,附件E中為有符號類型給出的實現限制是對稱的(例如INT_MAX <= 32767INT_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+1int值等於0x00000080(128)
  • 轉換為char ,將被截斷為char值0x80(-128)
  • 傳遞給printf ,它將擴展為int值0xFFFFFF80(-128)

由於您沒有在代碼中將其intchar ,因此int值0x00000080將“按原樣”傳遞給printf


上面的答案是基於您平台上的CHAR_BIT為8且sizeof(int)為4的假設。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM