C 語言中的整數提升



為了在整數的算術運算中保持一致性,C 編譯器會將某些資料型別提升到更高的級別。

除了標準的 int 資料型別之外,C 語言還允許您使用其子型別,例如 char、short int、long int 等。這些資料型別分別佔用不同的記憶體空間。例如,標準 int 的大小為 4 位元組,而 char 型別的大小為 2 位元組。當算術運算涉及長度不等的整數資料型別時,編譯器會採用整數提升策略。

整數提升

作為一般原則,小於 int整數型別在對其執行運算時會被提升。如果原始型別的所有值都可以在 int 中表示,則較小型別的值將轉換為int;否則,它將轉換為unsigned int

必須理解整數提升的概念才能編寫可靠的 C 程式碼,並避免與資料型別大小和對較小整數型別進行算術運算相關的意外問題。

示例

在此示例中,兩個變數ab 似乎儲存了相同的值,但它們並不相等。

#include <stdio.h>

int main(){

   char a = 251;
   unsigned char b = a;

   printf("a = %c", a);
   printf("\nb = %c", b);

   if (a == b)
      printf("\n Same");
   else
      printf("\n Not Same");
   
   return 0;
}

輸出

執行此程式碼時,將產生以下輸出:

a = √
b = √
Not Same

您得到此輸出是因為“a”和“b”在比較期間被視為整數。“a”是轉換為 int 的有符號 char,值為 -5,而“b”是轉換為 int 的無符號 char,值為 251。

示例:整數提升機制

讓我們嘗試透過此示例來了解整數提升的機制:

#include <stdio.h>

int main(){
   
   char a = 'e', b = '2', c = 'M';
   char d = (a * b) / c;
   
   printf("d as int: %d as char: %c", d, d);
   
   return 0;
}

輸出

執行程式碼並檢查其輸出:

d as int: 65 as char: A

何時應用整數提升?

在算術表示式“(a * b) / c”中,首先解決括號。所有變數都為有符號 char 型別,長度為 2 位元組,可以儲存 -128 到 127 之間的整數。因此,乘法超出了 char 的範圍,但編譯器不會報告任何錯誤。

當 C 編譯器處理涉及 char 等小型型別的算術運算時,會應用整數提升。在這些 char 型別相乘之前,編譯器會將其更改為 int 型別。因此,在這種情況下,(a * b) 轉換為 int,它可以容納乘法的結果,即 1200。

示例

整數提升作為通常的算術轉換的一部分應用於某些引數表示式;一元 +、- 和 ~ 運算子的運算元;以及移位運算子的運算元。請檢視以下示例:

#include <stdio.h>

int main(){

   char a = 10;
   int b = a >> 3;

   printf("b as int: %d as char: %c", b, b);

   return 0;
}

輸出

執行此程式碼時,將產生以下輸出:

b as int: 1 as char: 

在上面的示例中,將“a”的位結構向左移動三位仍然導致其值在 char 的範圍內(a << 3 的結果為 80)。

示例

在此示例中,char 變數的等級被提升為 int,以便其左移操作超出 char 型別的範圍。

#include <stdio.h>

int main(){

   char a = 50;
   int b = a << 2;
   
   printf ("b as int: %d as char: %c", b, b);
   
   return 0;
}

輸出

執行程式碼並檢查其輸出:

b as int: 200 as char: ╚

整數提升規則

提升規則幫助 C 編譯器保持一致性並避免意外結果。提升規則背後的基本原則是確保表示式的型別調整為容納所涉及的最寬資料型別,從而防止資料丟失或截斷。

以下是根據 C11 規範的提升規則摘要:

  • C 語言中的整數型別有 char、short、int、long、long long 和 enum。在進行型別提升時,布林值也被視為整數型別。

  • 任何兩個有符號整數型別都不應具有相同的等級,即使它們具有相同的表示形式。

  • 有符號整數型別的等級應大於任何精度較低的有符號整數型別的等級。

  • long int 的等級 > int 的等級 > short int 的等級 > signed char 的等級。

  • char 的等級等於 signed char 和 unsigned char 的等級。

  • 每當在表示式中使用小型整數型別時,它都會隱式轉換為 int,int 始終是有符號的。

  • 所有小型整數型別,無論符號如何,在大多數表示式中使用時都會隱式轉換為(有符號)int。

簡而言之,我們有以下整數提升規則:

  • 位元組和短整數值 - 它們被提升為 int。

  • 如果一個運算元為 long - 整個表示式被提升為 long。

  • 如果一個運算元為 float - 整個表示式被提升為 float。

  • 如果任何一個運算元為 double - 結果被提升為 double。

示例

這裡,變數xy 為 char 資料型別。當對它們執行除法運算時,它們會自動提升為 int,結果值儲存在z 中。

#include <stdio.h> 

int main(){
 
   char x = 68;
   char y = 34;
    
   printf("The value of x is: %d", x);
   printf("\nThe value of y is: %d", y);
    
   char z = x/y;
   printf("\nThe value of z: %d", z);
    
   return 0; 
}

輸出

執行此程式碼時,將產生以下輸出:

The value of x is: 68
The value of y is: 34
The value of z: 2
廣告