章节知识回顾
常量与字面量
- 常量是程序执行期间不可改变的值。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
?