关注

C++中双引号和单引号的区别(全面分析)

我在刷算法题的时候经常遇到,用了' '出现警告或者使用" "直接报错,尤其是在字符串部分(py玩家后遗症/(ㄒoㄒ)/~~)在详细了解后总结一下加强记忆。

总的来说在 C++ 中,双引号 "" 和单引号 '' 是完全不同的语法元素,数据类型、存储方式有所差异。

对比维度单引号 ''(字符常量)双引号 ""(字符串常量)
数据类型charconst char[](字符数组)
存储内容单个字符的 ASCII 码字符序列 + 末尾 '\0' 结束符
占用字节固定 1 字节字符数 + 1 字节(含 '\0'
内容限制仅 1 个字符(非空)0 个或多个字符(可空)
赋值对象char 变量const char* / char[]
隐式转换可转 int(ASCII 码)可转 const char*(首地址)
示例'5''\t''Z'"""abc""x\ny"

一、核心定义与数据类型

这是最根本的区别:单引号表示字符常量(char 类型),双引号表示字符串常量(const char[] 类型,本质是字符数组)

符号表示内容数据类型本质含义
'a'单个字符常量char单个 ASCII 字符
"a"字符串常量const char[]以 '\0' 结尾的字符数组

二、存储方式与字节长度

两者在内存中的存储形式和占用字节数完全不同,这是导致后续所有区别的根源。

1. 单引号(字符常量)
  • 存储:直接存储单个字符的 ASCII 码值,占用 1 个字节char 类型的标准大小)。
  • 示例:
    'A' 在内存中存储为 ASCII 码 65(二进制 01000001),仅占 1 字节。
  • 长度计算:sizeof('A') == 1(固定为 1,与字符无关)。
2. 双引号(字符串常量)
  • 存储:本质是 字符数组,除了显式的字符外,末尾会自动添加一个 '\0' 空字符(作为字符串结束标志),总占用字节数 = 显式字符数 + 1。
  • 示例:
    "A" 在内存中实际是 {'A', '\0'},占用 2 字节;
    "hello" 是 {'h','e','l','l','o','\0'},占用 6 字节。
  • 长度计算:
    • sizeof("A") == 2(包含 '\0' 的总字节数);
    • strlen("A") == 1strlen 统计 '\0' 之前的字符数,需包含 <cstring> 头文件)。

三、语法规则:内容限制不同

C++ 对两者的语法有严格限制,违反会导致编译错误。

1. 单引号 '' 的限制
  • 只能包含 1 个字符:不能为空('' 编译错误),也不能包含多个字符('ab' 是「多字符常量」,语法不推荐,值为各字符 ASCII 码的组合,结果不确定)。
  • 合法示例:'5''+''\n'(转义字符,本质是单个字符,ASCII 码为 10)。
  • 非法示例:''(空字符常量,错误)、'12'(多字符,不推荐)。
2. 双引号 "" 的限制
  • 可包含 0 个或多个字符:空字符串 "" 合法(仅存储 '\0',占 1 字节),多字符也合法(如 "123abc")。
  • 支持转义字符:如 "a\nb" 表示 'a'、换行符 '\n''b''\0',共 4 字节。
  • 合法示例:""(空字符串)、"Hello, C++""x\ty"(包含制表符)。
  • 非法示例:无本质非法内容,但需注意转义字符的正确性(如 "a\b" 合法,"a\z" 非法,因为 \z 不是有效转义符)。

下面代码最能体现区别

  string s3 =s1+s2;//bwabwa
  cout << s3<<endl;

  //-------------插入push_back()和insert()  push_back为void类型,删除erase()
  s1.push_back('c');
  string s4 = s1;  //bwac
  s4.insert(s4.begin(),'i');//ibwac
  s1.erase(s1.begin()+3); //bwa  s1.erase(s.begin() + 1, s.begin() + 3); 删除范围

  //--------------replace() repalce()函数:s.replace(pos,len,ss),将s从pos开始的len个字符替换成ss,
  s3.replace(2,2,"aa");  //bwabwa->bwaawa
  cout<<s3<<endl;
    //s.replace(pos,n1,n2,c),将s从pos开始的n1个字符替换成n2个字符c。
  s3.replace(2,2,1,'z'); //bwaawa-> bwzwa

四、如何选择区分

两者的使用场景严格依赖于变量 / 函数参数的类型,混用会导致编译错误。

1. 单引号 '' 的使用场景
  • 给 char 类型变量赋值:
    char c1 = 'a';    // 正确:char 变量匹配字符常量
    char c2 = 65;     // 正确:等价于 'A'(ASCII 码)
    char c3 = "a";    // 错误:字符串常量(const char[])无法赋值给 char 变量
    
  • 作为 char 类型参数传递给函数:
    putchar('B');     // 正确:putchar 接收 char 类型
    cout << 'c';      // 正确:输出 ASCII 码对应的字符(显示 'c')
    
2. 双引号 "" 的使用场景
  • 给字符串相关类型赋值(字符指针、字符数组):
    const char* s1 = "hello";  // 正确:字符串常量赋值给字符指针(指向常量区)
    char s2[] = "world";       // 正确:字符串常量初始化字符数组(会复制到栈区)
    char s3[6] = "hello";      // 正确:数组大小 = 字符数 + 1(包含 '\0')
    char s4[5] = "hello";      // 错误:数组大小不足(需 6 字节,实际仅存 5 个字符,无 '\0')
    
  • 作为字符串参数传递给函数:

    cpp

    puts("Hi!");              // 正确:puts 接收字符串常量
    strlen("test");           // 正确:计算字符串长度(结果为 4)
    cout << "C++";            // 正确:输出字符串(自动识别 '\0' 结束)
    

五、隐式转换与兼容性

1. 字符常量('c')的隐式转换
  • 可隐式转换为 int 类型(值为对应的 ASCII 码):
    int num = '0';  // 正确:num = 48('0' 的 ASCII 码)
    cout << 'z';    // 输出 122('z' 的 ASCII 码)
    
2. 字符串常量("c")的隐式转换
  • 可隐式转换为 const char* 类型(指向字符串的首地址),但不能转换为 int 或 char
    const char* p = "abc";  // 正确:p 指向 'a' 的地址
    int len = "abc";        // 错误:字符串无法直接转换为 int
    
  • 字符串常量是只读的:赋值给非 const 指针会导致未定义行为(C++11 后编译器会警告):
    char* p = "hello";      // 不推荐:"hello" 是 const,修改 p[0] 会崩溃
    const char* p = "hello";// 正确:明确只读,避免误修改
    

六、特殊情况:空值与转义字符

1. 空值处理
  • 字符常量无 “空值”:'' 非法,若需表示空字符,需用转义字符 '\0'(ASCII 码 0):
    char null_char = '\0';  // 正确:表示空字符(占 1 字节)
    
  • 字符串常量可有空值:"" 是合法的空字符串,仅包含 '\0'(占 1 字节):
    const char* empty_str = "";
    cout << strlen(empty_str);  // 输出 0(无有效字符)
    cout << sizeof(empty_str);  // 输出 8(指针大小,64 位系统)
    cout << sizeof("");         // 输出 1(仅 '\0')
    

2. 转义字符的使用
  • 单引号中:转义字符需用 \,如 '\'' 表示字符 ''\n' 表示换行符。
  • 双引号中:转义字符同样需用 \,如 "\"" 表示字符串 ""a\\b" 表示字符串 a\b

常见错误示例与原因

  1. 错误 1:字符串赋值给 char 变量
    char c = "a";  // 错误:类型不匹配(const char[] → char)
    
  2. 错误 2:单引号包含多个字符
    char c = 'ab'; // 不推荐:多字符常量,值为 0x6162(依赖编译器,结果不确定)
    

  3. 错误 3:字符串数组未留 '\0' 空间
    char arr[3] = "abc"; // 错误:"abc" 需 4 字节(含 '\0'),数组仅 3 字节,截断导致无结束符
    

  4. 错误 4:修改字符串常量
    char* s = "hello"; s[0] = 'H'; // 未定义行为:"hello" 是只读常量,修改会崩溃

转载自CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/weixin_47520540/article/details/151683441

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--