- 单引号 用于表示 字符 (Character),本质上是 一个整数(字符的ASCII码值)。
- 双引号 用于表示 字符串 (String),本质上是 一个字符指针,指向字符串在内存中的首地址。
详细解释
单引号 (') - 字符字面量
当你在代码中用单引号括起一个字符时,'A',你实际上是在使用该字符的ASCII码值(或其他字符编码标准,如Unicode)。

(图片来源网络,侵删)
- 数据类型:
char。 - 内存表示:它是一个单个字节(在标准C中)或一个
int类型(在某些实现中,用于表示扩展字符集,但其行为仍像一个字符),你可以把它看作是一个小的整数。 - 值:它代表字符本身对应的整数值。
'A'的值是65。'a'的值是97。'0'的值是48。'\n'(换行符) 的值是10。
示例代码:
#include <stdio.h>
int main() {
char ch1 = 'A';
char ch2 = '0'; // 注意,这是字符'0',不是数字0
// 1. 直接打印字符
printf("ch1 is: %c\n", ch1); // 输出: ch1 is: A
printf("ch2 is: %c\n", ch2); // 输出: ch2 is: 0
// 2. 打印字符对应的整数值 (ASCII码)
printf("The ASCII value of 'A' is: %d\n", ch1); // 输出: The ASCII value of 'A' is: 65
printf("The ASCII value of '0' is: %d\n", ch2); // 输出: The ASCII value of '0' is: 48
// 3. 可以进行算术运算,因为它本质上是整数
int result = 'A' + 1;
printf("'A' + 1 is: %c (ASCII: %d)\n", result, result); // 输出: 'A' + 1 is: B (ASCII: 66)
return 0;
}
双引号 (") - 字符串字面量
当你在代码中用双引号括起一串字符时,"Hello",C语言会做以下几件事:
- 在内存的静态存储区(通常是只读的)分配一段连续的空间。
- 将
'H', 'e', 'l', 'l', 'o'这几个字符依次存入这段空间。 - 在最末尾自动添加一个特殊的空字符
'\0',作为字符串的结束标志。 - 这个表达式的值,是这段内存空间的首地址(一个指针)。
- 数据类型:
char *(指向字符的指针)。 - 内存表示:它是一个指针,而不是字符本身。
- 值:它是一个内存地址,指向字符串的第一个字符。
示例代码:
#include <stdio.h>
int main() {
char *str = "Hello"; // str 是一个指针,指向 "Hello" 的首地址
// 1. 直接打印字符串
printf("str is: %s\n", str); // %s 会从str指向的地址开始打印,直到遇到'\0'
// 输出: str is: Hello
// 2. 打印指针本身的值(内存地址)
printf("The address of the string is: %p\n", (void*)str);
// 输出: The address of the string is: 0x... (一个具体的内存地址)
// 3. 打印字符串的第一个字符
printf("The first character is: %c\n", *str); // *str 解引用指针,获取地址上的值
// 输出: The first character is: H
// 4. 错误示例:你不能直接对字符串进行算术运算
// int wrong = "Hello" + 1; // 错误!不能对指针进行这种隐式转换和算术运算
// 正确的做法是移动指针:
char *second_char = str + 1;
printf("The second character is: %c\n", *second_char);
// 输出: The second character is: e
// 5. 字符串的长度不包括'\0'
// C标准库函数 strlen() 用于计算字符串长度
printf("The length of 'Hello' is: %zu\n", strlen("Hello"));
// 输出: The length of 'Hello' is: 5
return 0;
}
对比表格
| 特性 | 单引号 (') | 双引号 (") |
|---|---|---|
| 名称 | 字符字面量 | 字符串字面量 |
| 数据类型 | char (本质上是整数) |
char * (字符指针) |
| 内存表示 | 单个字节 (或int) | 一段连续的内存块,以 '\0'
|
| 表达式的值 | 字符的ASCII码值 | 字符串在内存中的首地址 |
| 用途 | 存储单个字符,参与字符运算 | 表示文本,用于字符串操作 |
| 示例 | char c = 'A'; |
char *s = "Hello"; |
| 长度 | 恒为 1 | strlen("abc") 为 3 (不含 '\0') |
常见错误与陷阱
理解了这个核心区别,就能避免很多常见的错误。

(图片来源网络,侵删)
错误1:用单引号定义字符串
// 错误! char str[] = 'Hello'; // 编译器会报错,因为 'H' 是一个 char,而 str[] 期望一个 char * 或一个字符数组。 // 正确写法: char str[] = "Hello"; // 这是一个字符数组初始化 // 或者 char *str = "Hello"; // 这是一个指针指向字符串字面量
错误2:混淆字符和字符串的赋值
char c; c = "A"; // 错误! "A" 是一个 char* (地址),不能赋值给 char c c = 'A'; // 正确! 'A' 是一个 char (整数)
错误3:忘记字符串以 '\0'
这是初学者最经典的错误之一。
char str1[5] = "Hello"; // 错误! "Hello" 需要 6 个字节 ('H','e','l','l','o','\0'),数组空间不足。
char str2[6] = "Hello"; // 正确! 足够容纳 5 个字符 + 1 个 '\0'。
// 更安全的做法是让编译器计算大小
char str3[] = "Hello"; // 编译器会自动分配 6 个字节的空间。
错误4:比较字符和字符串
char ch = 'A';
char *str = "A";
if (ch == str) { // 错误!比较的是字符 'A' 的整数值 (65) 和字符串 "A" 的内存地址。
// ...
}
if (ch == *str) { // 正确! *str 获取字符串的第一个字符 'A',再与 ch 比较。
// ...
}
if (strcmp(str, "A") == 0) { // 正确!使用 strcmp 函数来比较字符串内容。
// ...
}
记住这个简单的规则:单引号是字符,双引号是字符串,深入理解“字符是整数,字符串是指针”这个概念,将极大地帮助你在C语言编程中避免各种低级错误,写出更健壮、更地道的代码。
(图片来源网络,侵删)
这是初学者最经典的错误之一。
char str1[5] = "Hello"; // 错误! "Hello" 需要 6 个字节 ('H','e','l','l','o','\0'),数组空间不足。
char str2[6] = "Hello"; // 正确! 足够容纳 5 个字符 + 1 个 '\0'。
// 更安全的做法是让编译器计算大小
char str3[] = "Hello"; // 编译器会自动分配 6 个字节的空间。
错误4:比较字符和字符串
char ch = 'A';
char *str = "A";
if (ch == str) { // 错误!比较的是字符 'A' 的整数值 (65) 和字符串 "A" 的内存地址。
// ...
}
if (ch == *str) { // 正确! *str 获取字符串的第一个字符 'A',再与 ch 比较。
// ...
}
if (strcmp(str, "A") == 0) { // 正确!使用 strcmp 函数来比较字符串内容。
// ...
}
记住这个简单的规则:单引号是字符,双引号是字符串,深入理解“字符是整数,字符串是指针”这个概念,将极大地帮助你在C语言编程中避免各种低级错误,写出更健壮、更地道的代码。

(图片来源网络,侵删)
