C++基础总结:常量、字面量与字符串完全指南

章节知识回顾

常量与字面量

  • 常量是程序执行期间不可改变的值。C++支持两种常量:命名常量(named constants)和字面量(literals)。
    • 命名常量:与标识符关联的常量值。
    • 字面量常量:未关联标识符的常量值。

常量变量与类型限定符

  • 常量变量(constant variable)指值不可变的变量。
    • 使用 const 关键字声明常量变量,且必须初始化
    • 避免在按值传递或返回时使用 const
  • 类型限定符(type qualifier)修饰类型行为的关键字。
    • C++23 仅支持 constvolatile

常量表达式与编译时常量

  • 常量表达式(constant expression):可在编译时求值的表达式。
    • 非常量表达式称为运行时表达式(runtime expression)。
  • 编译时常量:值在编译时已知;运行时常量:初始化值在运行时才确定。

constexpr变量

  • constexpr 变量
    • 必须是编译时常量,并用常量表达式初始化。
    • 函数参数不能为 constexpr

字面量与魔数

  • 字面量:直接嵌入代码的值,具有类型。
    • 可通过字面量后缀(literal suffixes)修改默认类型。
  • 魔数(magic number):含义模糊或后续可能修改的字面量(多为数字)。
    • 避免使用魔数,改用符号常量(symbolic constants)。

数制系统

  • 十进制(10个数字)、二进制(2个数字)、八进制(base 8)、十六进制(base 16)。

字符串处理

  • 字符串(string):表示文本的字符序列。
    • 字符串字面量需用双引号包裹,类型为 C风格字符串(难用)。
    • std::string(需包含 <string>):更安全易用,但初始化和复制开销大。
    • std::string_view
      • 提供对现有字符串(C风格字面量、std::string 或字符数组)的只读访问,且不复制
      • 风险
        • 悬空视图(dangling view):当原字符串被销毁后访问视图。
        • 视图失效:原 std::string 被修改后,其所有视图均失效(使用将导致未定义行为)。
      • 安全用法:C风格字符串字面量存在于整个程序周期,因此可安全用于初始化或返回 std::string_view
  • 子字符串(substring):字符串中的连续字符序列。

章节练习题

问题1:常量使用

  1. 为何命名常量通常比字面量常量更优? (显示答案)
  2. 为何 const/constexpr 变量通常比 #define 定义的符号常量更优? (显示答案)

问题2:代码调试

找出以下代码的3处问题:

#include <cstdint> // for std::uint8_t
#include <iostream>

int main()
{
    std::cout << "How old are you?\n";
    std::uint8_t age{};
    std::cin >> age; // 问题点
    std::cout << "Allowed to drive a car in Texas: ";
    if (age >= 16)
        std::cout << "Yes";
    else
        std::cout << "No";
    std::cout << '.\n'; // 问题点
    return 0;
}

期望输出示例

How old are you?
6
Allowed to drive a car in Texas: No
How old are you?
19
Allowed to drive a car in Texas: Yes

(显示答案)

问题3:字符串处理

  1. std::stringstd::string_view 的主要区别是什么?
  2. 使用 std::string_view 时可能出现什么问题? (显示答案)

问题4:综合练习

编写程序:输入两人的姓名和年龄,并输出年长者。

运行示例

Enter the name of person #1: John Bacon
Enter the age of John Bacon: 37
Enter the name of person #2: David Jenkins
Enter the age of David Jenkins: 44
David Jenkins (age 44) is older than John Bacon (age 37).

(显示提示) (显示答案)

问题5:深入思考

在问题4的解决方案中,为何 main 函数中的变量 age1 不能声明为 constexpr

关注公众号,回复"cpp-tutorial"

可领取价值199元的C++学习资料

公众号二维码

扫描上方二维码或搜索"cpp-tutorial"