
- C 程式設計教程
- C - 首頁
- C 語言基礎
- C - 概述
- C - 特性
- C - 歷史
- C - 環境搭建
- C - 程式結構
- C - Hello World
- C - 編譯過程
- C - 註釋
- C - 詞法單元
- C - 關鍵字
- C - 識別符號
- C - 使用者輸入
- C - 基本語法
- C - 資料型別
- C - 變數
- C - 整數提升
- C - 型別轉換
- C - 型別強制轉換
- C - 布林型別
- C 語言中的常量和字面量
- C - 常量
- C - 字面量
- C - 轉義序列
- C - 格式說明符
- C 語言中的運算子
- C - 運算子
- C - 算術運算子
- C - 關係運算符
- C - 邏輯運算子
- C - 位運算子
- C - 賦值運算子
- C - 一元運算子
- C - 自增和自減運算子
- C - 三元運算子
- C - sizeof 運算子
- C - 運算子優先順序
- C - 其他運算子
- C 語言中的決策語句
- C - 決策語句
- C - if 語句
- C - if...else 語句
- C - 巢狀 if 語句
- C - switch 語句
- C - 巢狀 switch 語句
- C 語言中的迴圈語句
- C - 迴圈語句
- C - while 迴圈
- C - for 迴圈
- C - do...while 迴圈
- C - 巢狀迴圈
- C - 無限迴圈
- C - break 語句
- C - continue 語句
- C - goto 語句
- C 語言中的函式
- C - 函式
- C - 主函式
- C - 按值呼叫函式
- C - 按引用呼叫函式
- C - 巢狀函式
- C - 可變引數函式
- C - 使用者自定義函式
- C - 回撥函式
- C - 返回語句
- C - 遞迴
- C 語言中的作用域規則
- C - 作用域規則
- C - 靜態變數
- C - 全域性變數
- C 語言中的陣列
- C - 陣列
- C - 陣列的特性
- C - 多維陣列
- C - 將陣列傳遞給函式
- C - 從函式返回陣列
- C - 變長陣列
- C 語言中的指標
- C - 指標
- C - 指標和陣列
- C - 指標的應用
- C - 指標運算
- C - 指標陣列
- C - 指標到指標
- C - 將指標傳遞給函式
- C - 從函式返回指標
- C - 函式指標
- C - 指向陣列的指標
- C - 指向結構體的指標
- C - 指標鏈
- C - 指標與陣列
- C - 字元指標和函式
- C - 空指標
- C - void 指標
- C - 野指標
- C - 解引用指標
- C - 近、遠和巨型指標
- C - 指標陣列的初始化
- C - 指標與多維陣列
- C 語言中的字串
- C - 字串
- C - 字串陣列
- C - 特殊字元
- C 語言中的結構體和聯合體
- C - 結構體
- C - 結構體和函式
- C - 結構體陣列
- C - 自引用結構體
- C - 查詢表
- C - 點 (.) 運算子
- C - 列舉 (或 enum)
- C - 結構體填充和打包
- C - 巢狀結構體
- C - 匿名結構體和聯合體
- C - 聯合體
- C - 位域
- C - Typedef
- C 語言中的檔案處理
- C - 輸入和輸出
- C - 檔案 I/O(檔案處理)
- C 預處理器
- C - 預處理器
- C - 編譯指示
- C - 預處理器運算子
- C - 宏
- C - 標頭檔案
- C 語言中的記憶體管理
- C - 記憶體管理
- C - 記憶體地址
- C - 儲存類
- 其他主題
- C - 錯誤處理
- C - 可變引數
- C - 命令執行
- C - 數學函式
- C - static 關鍵字
- C - 隨機數生成
- C - 命令列引數
- C 程式設計資源
- C - 問答
- C - 快速指南
- C - 速查表
- C - 有用資源
- C - 討論
C 語言中的整數提升
為了在整數的算術運算中保持一致性,C 編譯器會將某些資料型別提升到更高的級別。
除了標準的 int 資料型別之外,C 語言還允許您使用其子型別,例如 char、short int、long int 等。這些資料型別分別佔用不同的記憶體空間。例如,標準 int 的大小為 4 位元組,而 char 型別的大小為 2 位元組。當算術運算涉及長度不等的整數資料型別時,編譯器會採用整數提升策略。
整數提升
作為一般原則,小於 int 的整數型別在對其執行運算時會被提升。如果原始型別的所有值都可以在 int 中表示,則較小型別的值將轉換為int;否則,它將轉換為unsigned int。
必須理解整數提升的概念才能編寫可靠的 C 程式碼,並避免與資料型別大小和對較小整數型別進行算術運算相關的意外問題。
示例
在此示例中,兩個變數a 和b 似乎儲存了相同的值,但它們並不相等。
#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。
示例
這裡,變數x 和y 為 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