这一章的标题是《第三章:对象、类型和值》
对象
首先,什么是"对象"?对象的意思是,存储一个特定类型的内存区域, 或者说,对象就是一个"容器",容纳的是一个特定的类型:
也提到了避免重复的理由:
- 我们是程序员,不是打字员
- 不必要的重复,为出错提供了机会,应该避免
变量
具有名字的对象,称为变量
类型
BS 认为 C++ 最常用的5种类型是:
- int
- double
- char
- string
- bool
不过就我个人而言,BS在瞎逼逼,真正常用的类型是: - int
- float
- char
- void
- bool
- string
- vector
- unordered_map
程序1 - 检测重复输入的单词
输入字符串序列,打印每个字符串序列中的重复的单词。重复,指的是和前一个单词相同。
cpp
void detect_repeated_words()
{
std::string previous{};
std::string current;
while (std::cin >> current)
{
if (current == previous)
{
std::cout << "repeated word:" << current << '\n';
}
previous = current;
}
}
// 测试函数
void test_detect_repeated_words()
{
std::vector<std::string> text_list = {
"The cat cat jumped",
"She she laughed He He He because what he did did not look very very good good"
};
for (const std::string& text: text_list) {
// 使用字符串流来模拟输入
std::istringstream input(text);
// 将 cin 缓存
auto cin_buf = std::cin.rdbuf();
// 重定向 cin 到字符串流
std::cin.rdbuf(input.rdbuf());
// 调用原始函数
detect_repeated_words();
// 恢复 cin
std::cin.rdbuf(cin_buf);
}
}
程序2 - 打印重复单词出现的位置
cpp
// 精细化的重复单词统计:打印重复单词在序列中出现的位置
void detect_repeated_words_stats()
{
std::string previous{};
std::string current;
int number_of_words = 0;
while (std::cin >> current)
{
number_of_words++;
if (current == previous)
{
std::cout << "word number " << number_of_words
<< " repeated: " << current << '\n';
}
previous = current;
}
}
在程序的早期版本上修改。这确实可以节省一些时间,但是有前提:
- 需要对早期版本很熟悉,如果不是自己的代码,可能做不到
- 有很多成功的案例,是新写代码,而不是用老的代码,如 ncnn, vllm
- 普通人呢,用老的代码,可以快速糊一个新的程序,但是代码质量,取决于老代码质量,如果老代码不干净,那就是越来越难以维护;但是代码并不总是需要可维护,有写代码是一次性的
命名 - 请不要和标准库的标识符同名
如下代码定义了函数 vector()
, 和标准库里的 vector 同名了,如果此时 using namespace std
, 那么会导致编译报错
cpp
#include <vector>
using namespace std;
// 定义一个与标准库中名字重合的函数
void vector()
{
std::cout << "This is a custom function named vector." << std::endl;
}
int test_duplicated_name_with_std()
{
// 尝试调用自定义的 vector 函数
vector();
// 使用标准库中的 vector 类
std::vector<int> numbers = {1, 2, 3, 4, 5};
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
总结
这一章的大部分内容都很基础,常规的 C/C++ 书或课程已经覆盖到了。
唯二需要留意的是:
- 用户自定义标识符(变量名、函数名),请避开标准库,这样说来,也尽量不要用
using namespace std
- 数据类型转换的精度丢失,例如 double 转 int,在小的程序中不重要,基本可控;但是大型程序中容易导致问题,应当尽量避免出现