1?字符類型概述
????????在 C 語言中,字符類型 char 用于表示單個字符,例如一個數字、一個字母或一個符號。
????????char 類型的字面量是用單引號括起來的單個字符,例如 'A'、'5' 或 '#'。
????????當需要表示多個字符組成的序列時,就涉及到了字符串。在 C 語言中,字符串是通過 char 數組來實現的,數組屬于構造類型,而非基本數據類型。關于數組和字符串的詳細內容,我們將在后續章節專門講解。
// 定義并初始化 char 類型變量
char letter = 'A'; // 字母
char digit = '5'; // 數字
char symbol1 = '#'; // 符號
char symbol2 = '\n'; // 轉義字符,換行符// 錯誤定義:不是單個字符
// char letters = 'AB'; // 錯誤:字符常量只能包含一個字符
// char digits = '12'; // 錯誤:字符常量只能包含一個字符
// char symbols = '#$'; // 錯誤:字符常量只能包含一個字符
// char chinese = '中'; // 錯誤:一個漢字字符在 UTF-8 編碼中占用多個字節// 可以通過后續學習字符串來存儲多個字符
// char str1[] = "Hello"; // 正確:字符串常量可以包含多個字符
2 轉義字符
????????在 C 語言中,可以使用以反斜杠 \ 開頭的轉義字符來表示一些具有特殊含義的字符。這些轉義字符為程序提供了處理特殊字符和格式化輸出的能力。
2.1 常見轉義字符說明
????????以下是常見的轉義字符及其說明:
轉義字符 | 字符名稱 | 說明 |
---|---|---|
\n | 換行符 | 將光標移動到下一行的開頭(換行),兩個 \n 表示空一行 |
\t | 水平制表符 | 插入一個水平制表符(通常等效于 4 或 8 個空格,具體取決于實現) |
\\ | 反斜杠字符 | 由于反斜杠在 C 語言中用作轉義字符的引導,所以表示它自身時需要使用兩個反斜杠 |
\' | 單引號字符 | 因為在 C 語言中字符常量是由單引號括起來的,所以要在字符串中表示單引號,就需要使用轉義字符 |
\" | 雙引號字符 | 因為 C 語言中的字符串是由雙引號括起來的,所以要在字符串中表示雙引號,就需要使用轉義字符 |
\a | 響鈴(BEL)字符 | 產生聲音或可視信號(具體效果取決于系統和終端) |
\b | 退格符 | 將光標向左移動一個位置(可能刪除左側字符,具體行為依賴實現) |
\f | 換頁符 | 將光標移動到下一頁的開頭(具體效果取決于系統和終端) |
\r | 回車符 | 將光標移動到當前行的開頭(可能覆蓋已有內容,不換行) |
\v | 垂直制表符 | 在垂直方向上移動光標(效果因系統而異) |
\ooo | 八進制轉義序列 | 用 1 到 3 位八進制數字(0~7)表示字符,示例:\101 → 八進制 101(十進制 65)→ 字符 'A' 注意:位數不足 3 時,編譯器按實際八進制值解析(如 \12 等價于 \012,表示換行符 \n) |
\xhh | 十六進制轉義序列 | 用 1 到多位十六進制數字(0~9、A~F、a~f)表示字符,示例:\x41 → 十六進制 41(十進制 65)→ 字符 'A' 注意:通常用 2 位表示 ASCII 字符(如 \x41),但長度靈活(如 \x1F600 表示 Unicode 笑臉 😀) |
- 某些轉義字符(如 \a、\b、\f、\v)的效果可能因終端或系統而異。
- 八進制和十六進制轉義序列直接對應 ASCII 碼,可通過查表驗證輸出。
擴展:轉義字符中的?\r(回車)與 \n(換行)
- 起源與功能
- \r(回車):將光標移回行首(打字機時代功能),不換行。
- \n(換行):將光標移到下一行(紙張滾動功能),不移動行首位置。
- 系統差異
- Unix/Linux/macOS:僅用 \n 表示換行。
- Windows:傳統用 \r\n 組合,但現代工具兼容 \n(網絡協議仍需 \r\n)。
- C 語言中的抽象
- C 語言統一用 \n 表示換行,實際行為由系統底層決定(如 Unix 直接換行,Windows 可能轉換為 \r\n)。
2.2 案例演示
????????以下是一個 C 程序,演示了上表中所列出的轉義字符的用法,并附有詳細注釋:
#include <stdio.h>int main()
{// 1. 換行符 \n:將光標移動到下一行的開頭(換行)printf("這是第一行\n這是第二行\n\n"); // 兩個 \n 表示空一行// 2. 水平制表符 \t:插入一個水平制表符(通常等效于 4 或 8 個空格,具體取決于實現)printf("姓名:\t張三\n年齡:\t25\n\n");// 3. 反斜杠字符 \\:表示一個反斜杠本身printf("路徑示例: C:\\\\Program Files\\\n\n"); // 路徑示例: C:\\Program Files\// 4. 單引號字符 \':在字符常量中表示單引號printf("單引號示例: \'A\'\n\n"); // 單引號示例: 'A'// 5. 雙引號字符 \":在字符串中表示雙引號printf("雙引號示例: \"Hello\"\n\n"); // 雙引號示例: "Hello"// 6. 響鈴字符 \a:產生聲音或可視信號(具體效果取決于系統和終端)printf("響鈴提示:\a 請注意!\n\n");// 7. 退格符 \b:將光標向左移動一個位置(可能刪除左側字符,具體行為依賴實現)printf("退格示例: 12\b3\n\n"); // 輸出可能為 "13",因為 \b 可能會刪除左側的字符 '2'// 8. 換頁符 \f:將光標移動到下一頁的開頭(具體效果取決于系統和終端)printf("第一頁\f這是第二頁的內容\n\n");// 9. 回車符 \r:將光標移動到當前行的開頭(可能覆蓋已有內容,不換行)printf("123\r456\n\n"); // 輸出 "456",因為 \r 覆蓋了前面的 "123"// 10. 垂直制表符 \v:在垂直方向上移動光標(效果因系統而異)printf("垂直制表符:\v新行1\v新行2\n\n");// 11. 八進制轉義序列 \ooo:用 1 到 3 位八進制數字(0~7)表示字符printf("八進制示例: \101\n"); // \101 對應 ASCII 碼 65,即 'A'printf("八進制示例: \12\n"); // \12 對應 ASCII 碼 10,即換行符 \nprintf("八進制示例: \141\n\n"); // \141 對應 ASCII 碼 97,即 'a'// 12. 十六進制轉義序列 \xhh:用 1 到多位十六進制數字(0~9、A~F、a~f)表示字符printf("十六進制示例: \x41\n"); // \x41 對應 ASCII 碼 65,即 'A'printf("十六進制示例: \x0A\n"); // \x0A 對應 ASCII 碼 10,即換行符 \nprintf("十六進制示例: \x61\n"); // \x61 對應 ASCII 碼 97,即 'a'return 0;
}
????????程序在 VS Code 中的運行結果如下所示:
2.3 單雙引號轉義使用要點
????????在 C 語言中,字符串是由雙引號 " " 括起來的字符序列。當我們需要在字符串中合理使用單引號和雙引號時,需要遵循特定規則:
- 單引號在字符串中的使用:在由雙引號包圍的字符串內部,可以直接使用單引號,無需進行轉義。因為單引號在這里被當作字符串的普通字符內容,而非界定字符常量的符號。例如:
printf("This is a 'character' inside a string.\n");
// 輸出結果:This is a 'character' inside a string.
????????上述代碼執行后,會正常輸出字符串,其中單引號會被當作字符串的一部分輸出,輸出結果為:This is a 'character' inside a string.
- 雙引號在字符串中的使用:由于雙引號本身用于界定字符串的開始和結束,所以不能直接在雙引號界定的字符串內部使用另一個未轉義的雙引號。若要在字符串中包含雙引號字符,必須使用轉義字符 \ 對其進行轉義。經過轉義后,緊隨轉義字符的雙引號就會被視為字符串的一部分,而非字符串的結束標志。如下圖所示:
3 字符類型格式占位符
????????在 C 語言中,使用格式化輸出函數(如 printf)時,針對 char 類型的數據,有不同的格式占位符來滿足不同的輸出需求:
- 使用 %c 格式化占位符,可以直接輸出 char 類型的字符本身。例如,printf("%c", 'a'); 會輸出字符 a。
- 使用 %d 格式化占位符,可以輸出該字符對應的 ASCII 碼值。例如,printf("%d", 'a'); 會輸出 97,即字符 'a' 在 ASCII 碼表中的十進制數值。
#include <stdio.h>int main()
{// 定義一個字符變量char c = 'a';// 使用 %c 輸出字符本身printf("使用 %%c 輸出字符: %c\n", c); // 輸出: a// 使用 %d 輸出字符對應的 ASCII 碼值printf("使用 %%d 輸出 ASCII 碼值: %d\n", c); // 輸出: 97return 0;
}
????????程序在 VS Code 中的運行結果如下所示:
4 字符類型的本質
????????在 C 語言中,char 類型本質上是一個整數類型,它對應著 ASCII 碼表中的數字,其存儲長度固定為 1 個字節(8 位)。
????????字符型可進一步細分為 signed char(有符號字符類型)和 unsigned char(無符號字符類型)。
- signed char 的取值范圍是 -128 到 127。
- unsigned char 的取值范圍是 0 到 255。
????????在實際使用中,char 類型默認是否帶符號取決于當前的運行環境。
????????可通過 <limits.h> 頭文件中的宏定義直接獲取取值范圍:
- SCHAR_MIN / SCHAR_MAX:signed char 的最小 / 最大值。
- UCHAR_MAX:unsigned char 的最大值(最小值固定為 0)。
????????字符型數據在存儲和讀取過程中,會涉及到 ASCII 碼的轉換。例如,字符 'a' 在 ASCII 碼表中對應的十進制數字是 97,在存儲時以二進制形式存儲,讀取時再根據 ASCII 碼表還原為字符 'a'。具體過程可參考下圖:
#include <stdio.h>
#include <limits.h> // 用于獲取字符類型的范圍int main()
{// 1. 驗證 char 類型的存儲長度printf("char 類型的存儲長度: %zu 字節\n", sizeof(char)); // 輸出: 1 字節// 2. 輸出 signed char 和 unsigned char 的范圍printf("signed char 范圍: %d 到 %d\n", SCHAR_MIN, SCHAR_MAX); // -128 到 127printf("unsigned char 范圍: 0 到 %u\n", UCHAR_MAX); // 0 到 255// 3. 演示 char 類型的整數特性(ASCII 碼值)char c = 'A'; // 字符 'A' 對應 ASCII 碼 65printf("字符 '%c' 的 ASCII 碼值: %d\n", c, c); // 輸出: 65// 3.1 通過整數操作修改字符,驗證 char 類型的整數特性c = c + 1; // ASCII 碼值 +1,'A' -> 'B'printf("修改后的字符(+1): '%c'(ASCII 碼值: %d)\n", c, c); // 輸出: 'B' 和 66c = c - 1; // ASCII 碼值 -1,'B' -> 'A'printf("修改后的字符(-1): '%c'(ASCII 碼值: %d)\n", c, c); // 輸出: 'A' 和 65// 3.2 定義 unsigned char 類型變量,存儲整數值,驗證 char 類型的整數特性unsigned char d = 67; // 存儲 ASCII 碼值 67,對應字符 'C'// char 類型整數字面量沒有后綴形式,這里的 67 其實是 int 類型,編譯器進行了隱式類型轉換printf("字符 '%c'(ASCII 碼值: %d)\n", d, d); // 輸出: 'C' 和 67// 3.3 定義 int 類型數據,存儲整數值,驗證 char 類型的整數特性int i = 68;printf("字符 '%c'(ASCII 碼值: %d)\n", i, i); // 輸出: 'D' 和 68return 0;
}
????????程序在 VS Code 中的運行結果如下所示:
5 整數/浮點/字符類型的最值宏匯總
????????在 C 語言中,可以通過引入頭文件 <limits.h>(整數 / 字符類型)和 <float.h>(浮點數類型),使用宏定義來獲取各種類型的取值范圍。以下是分類總結:
5.1 整數類型(包括 char)
????????需引入頭文件:#include <limits.h>
????????最值宏名稱及其含義:
類型 | 宏定義 | 含義 | 示例值(32 位系統) |
---|---|---|---|
char | CHAR_MIN ?/?CHAR_MAX | 默認?char ?的最小 / 最大值(符號性取決于環境) | 依賴編譯器(可能是?-128 ?到?127 ?或?0 ?到?255 ) |
signed char | SCHAR_MIN | signed char ?的最小值 | -128 |
SCHAR_MAX | signed char ?的最大值 | 127 | |
unsigned char | UCHAR_MAX | unsigned char ?的最大值 | 255 |
short | SHRT_MIN | short ?的最小值 | -32768 |
SHRT_MAX | short ?的最大值 | 32767 | |
unsigned short | USHRT_MAX | unsigned short ?的最大值 | 65535 |
int | INT_MIN | int ?的最小值 | -2147483648 |
INT_MAX | int ?的最大值 | 2147483647 | |
unsigned int | UINT_MAX | unsigned int ?的最大值 | 4294967295 |
long | LONG_MIN | long ?的最小值 | 依賴系統(如?-2147483648 ) |
LONG_MAX | long ?的最大值 | 依賴系統(如?2147483647 ) | |
unsigned long | ULONG_MAX | unsigned long ?的最大值 | 依賴系統(如?4294967295 ) |
long long | LLONG_MIN | long long ?的最小值 | -9223372036854775808 |
LLONG_MAX | long long ?的最大值 | 9223372036854775807 | |
unsigned long long | ULLONG_MAX | unsigned long long ?的最大值 | 18446744073709551615 |
5.2 浮點數類型
????????需引入頭文件:#include <float.h>
????????最值宏名稱及其含義:
類型 | 宏定義 | 含義 | 示例值(IEEE 754 標準) |
---|---|---|---|
float | FLT_MIN | 最小正規范化值(非零最小值) | 1.175494e-38 |
FLT_MAX | 最大有限值 | 3.402823e+38 | |
FLT_EPSILON | 機器 epsilon(最小可表示差值) 即 1.0 與比 1.0 大的最小可表示單精度浮點數之間的差值,用于判斷單精度浮點數的近似相等性或分析數值穩定性 | 1.192093e-7 | |
double | DBL_MIN | 最小正規范化值(非零最小值) | 2.225074e-308 |
DBL_MAX | 最大有限值 | 1.797693e+308 | |
DBL_EPSILON | 機器 epsilon(最小可表示差值) 即 1.0 與比 1.0 大的最小可表示雙精度浮點數之間的差值,用于雙精度浮點數的誤差分析和比較 | 2.220446e-16 | |
long double | LDBL_MIN | 最小正規范化值(非零最小值) | 依賴系統(如?3.362103e-4932 ) |
LDBL_MAX | 最大有限值 | 依賴系統(如?1.189731e+4932 ) | |
LDBL_EPSILON | 機器 epsilon(最小可表示差值) 即 1.0 與比 1.0 大的最小可表示長雙精度浮點數之間的差值,用于長雙精度浮點數的高精度計算 | 依賴系統(如?1.084202e-19 ) |
- 機器 epsilon 是浮點數格式的最小上界,使得 1.0 + ε > 1.0 為真。它反映了浮點數的相對精度。典型用途如下:
- 浮點數比較(判斷近似相等性)。
- 數值算法的誤差分析。
- 避免浮點運算中的累積誤差問題。
6 ASCII 碼
????????ASCII(American Standard Code for Information Interchange,美國信息交換標準代碼)是一種用于表示文本字符的字符編碼標準。它總共規定了 128 個字符的編碼。
????????在 ASCII 碼體系中,不同字符對應著特定的十進制和二進制編碼。例如:
- 空格字符 “SPACE” 的 ASCII 碼值為 32,其二進制表示為 0010 0000。
- 數字字符 0 的 ASCII 碼值為 48,二進制表示為 0011 0000。
- 大寫字母 A 的 ASCII 碼值為 65,二進制表示為 0100 0001。
- 小寫字母 a 的 ASCII 碼值為 97,二進制表示為 0110 0001。
????????通過 ASCII 碼,計算機能夠以統一的方式存儲、處理和傳輸文本字符,確保不同系統之間文本信息的準確交互。
7 編程練習
7.1?字符輸出與格式化
????????定義三個 char 變量,分別存儲字母、數字和符號,然后使用 printf 格式化輸出它們的值和 ASCII 碼。
#include <stdio.h>int main()
{char letter = 'B';char digit = '7';char symbol = '@';printf("字母: %c (ASCII: %d)\n", letter, letter); // 字母: B (ASCII: 66)printf("數字: %c (ASCII: %d)\n", digit, digit); // 數字: 7 (ASCII: 55)printf("符號: %c (ASCII: %d)\n", symbol, symbol); // 符號: @ (ASCII: 64)return 0;
}
????????程序在 VS Code 中的運行結果如下所示:
7.2 固定字母大小寫轉換
????????定義一個 char 變量存儲大寫字母 'A',通過算術運算將其轉換為小寫字母 'a' 并輸出。再定義一個 char 變量存儲小寫字母 'z',通過算術運算將其轉換為大寫字母 'Z' 并輸出。
#include <stdio.h>int main()
{// 大寫字母 'A' 轉小寫字母 'a'char upper = 'A';upper = upper + 32; // ASCII 碼 +32printf("大寫 'A' 轉換為小寫: %c\n", upper); // 輸出 'a'// 小寫字母 'z' 轉大寫字母 'Z'char lower = 'z';lower = lower - 32; // ASCII 碼 -32printf("小寫 'z' 轉換為大寫: %c\n", lower); // 輸出 'Z'return 0;
}
- 掌握大小寫字母的轉換方法(大寫字母的 ASCII 碼 +32 得到小寫字母,反之 -32)。?
????????程序在 VS Code 中的運行結果如下所示:
7.3?字符與數字的混合運算
- 定義一個 char 變量存儲數字字符 '5',通過算術運算將其轉換為整數 5 并輸出。
- 定義一個 int 變量存儲整數 3,通過算術運算將其轉換為字符 '3' 并輸出。
- 對字符 '5' 和整數 3 進行混合運算(如相加),并分別以字符和整數形式輸出結果。
#include <stdio.h>int main()
{// 數字字符 '5' 轉整數 5char digit_char = '5';int digit_int = digit_char - '0'; // ASCII 碼相減printf("字符 '%c' 對應的整數: %d\n", digit_char, digit_int); // 輸出 5// 整數 3 轉字符 '3'int num = 3;char num_char = num + '0'; // ASCII 碼相加printf("整數 %d 對應的字符: %c\n", num, num_char); // 輸出 '3'// 混合運算char mixed_char = digit_char + num; // '5' + 3 = '8'// 以 %c 和 %d 輸出結果printf("混合運算結果(字符:): %c\n", mixed_char); // 輸出 '8'printf("混合運算結果(整數:): %d\n", mixed_char); // 輸出 56(53+3)return 0;
}
????????程序在 VS Code 中的運行結果如下所示:
7.4?字符的對稱轉換
????????定義一個 char 變量存儲字母 'd',通過算術運算將其轉換為字母表中對稱的字母(如 'a' ? 'z','b' ? 'y','c' ? 'x','d' ? 'w')并輸出。
#include <stdio.h>int main()
{char c = 'd';// 計算對稱字母:'a' + ('z' - c)c = 'a' + ('z' - c);printf("字母 '%c' 的對稱字母: %c\n", 'd', c); // 輸出 'w'return 0;
}
- 對稱字母 = 字母表起始位置 + (字母表末尾位置 - 當前字母位置)
????????程序在 VS Code 中的運行結果如下所示:
7.5 字符的循環偏移
????????定義一個 char 變量存儲字母 'X',通過算術運算將其轉換為字母表中后第 5 個字母(如 'X' → 'C',注意字母表的循環)。
#include <stdio.h>int main()
{char c = 'X';// 計算循環偏移:((c - 'A' + 5) % 26) + 'A'// % 是求余數運算符c = ((c - 'A' + 5) % 26) + 'A';printf("字母 '%c' 后第 5 個字母(循環): %c\n", 'X', c); // 輸出 'C'return 0;
}
- 偏移后字母 = 'A' + ((當前字母位置 + 偏移量) % 26)?
- c - 'A':將字母轉換為 0 到 25 的位置。
- + n:向后偏移 n 個位置。
- % 26:處理字母表的循環(超過 'Z' 時回到 'A')。
- + 'A':將位置轉換回 ASCII 字符。
????????程序在 VS Code 中的運行結果如下所示: