常量与字面量
- 常量是程序执行期间不可改变的值。C++支持两种常量:命名常量(named constants)和字面量(literals)。- 命名常量:与标识符关联的常量值。
- 字面量常量:未关联标识符的常量值。
 
常量变量与类型限定符
- 常量变量(constant variable)指值不可变的变量。- 使用 const关键字声明常量变量,且必须初始化。
- 避免在按值传递或返回时使用 const。
 
- 使用 
- 类型限定符(type qualifier)修饰类型行为的关键字。- C++23 仅支持 const和volatile。
 
- C++23 仅支持 
常量表达式与编译时常量
- 常量表达式(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。
 
- 提供对现有字符串(C风格字面量、
 
- 子字符串(substring):字符串中的连续字符序列。
章节练习题
问题1:常量使用
- 为何命名常量通常比字面量常量更优? (显示答案)
- 为何 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:字符串处理
- std::string和- std::string_view的主要区别是什么?
- 使用 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?
