章节回顾
常量是在程序执行期间不能更改的值。C++ 支持两种类型的常量:命名常量和字面量。
命名常量是与标识符关联的常量值。字面量常量是未与标识符关联的常量值。
其值不能更改的变量称为常量变量。const 关键字可用于使变量成为常量。常量变量必须初始化。避免在按值传递或按值返回时使用 const
。
类型限定符是应用于类型以修改该类型行为方式的关键字。截至 C++23,C++ 仅支持 const
和 volatile
作为类型限定符。
常量表达式是可以在编译时求值的表达式。不是常量表达式的表达式有时称为运行时表达式。
编译时常量是其值在编译时已知的常量。运行时常量是其初始化值直到运行时才已知的常量。
constexpr 变量必须是编译时常量,并用常量表达式初始化。函数参数不能是 constexpr。
字面量是直接插入到代码中的值。字面量具有类型,字面量后缀可用于将字面量的类型从默认类型更改。
魔法数字是字面量(通常是数字),其含义不明确或以后可能需要更改。不要在代码中使用魔法数字。相反,请使用符号常量。
在日常生活中,我们使用有10个数字的十进制数进行计数。计算机使用只有2个数字的二进制。C++ 还支持八进制(基数8)和十六进制(基数16)。这些都是数字系统的示例,数字系统是用于表示数字的符号(数字)的集合。
字符串是用于表示文本(例如名称、单词和句子)的连续字符集合。字符串字面量始终放置在双引号之间。C++ 中的字符串字面量是 C 风格字符串,它们具有难以处理的奇怪类型。
std::string 提供了一种简单安全地处理文本字符串的方法。std::string 位于 <string> 头文件中。std::string
的初始化(或赋值)和复制成本很高。
std::string_view 提供对现有字符串(C 风格字符串字面量、std::string 或 char 数组)的只读访问,而不进行复制。正在查看已销毁字符串的 std::string_view
有时称为悬空视图。当 std::string
被修改时,所有对该 std::string
的视图都将失效,这意味着这些视图现在无效。使用失效的视图(除了重新验证它)将产生未定义的行为。
由于 C 风格字符串字面量存在于整个程序中,因此可以将 std::string_view
设置为 C 风格字符串字面量,甚至可以从函数返回此类 std::string_view
。
子字符串是现有字符串中连续的字符序列。
小测验时间
问题 #1
为什么命名常量通常比字面量常量更好?
为什么 const/constexpr 变量通常比 #defined 符号常量更好?
问题 #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
在上述测验的解决方案中,为什么 main
中的变量 age1
不能是 constexpr?