零散的笔记素材
这里一般用来存放在日常代码编写中遇到问题 - 查找资料的过程中学习到的知识点,由于这些知识点往往非常重要但是暂时又不知到应该放在哪里,所以使用这个文件来临时存放直到找到它们应该被记录的位置。
基于范围的 for
循环详解
基于范围的 for
循环是 C++11 引入的简化遍历容器(如数组、std::vector
、std::map
等)的语法。它提供了一种简单、直接的方式来访问容器中的元素,避免了传统 for
循环中手动管理索引或迭代器的麻烦。
基本语法
for (declaration : expression) {
// 循环体
}
declaration
:循环中每次迭代时用来表示容器中单个元素的变量。expression
:表示一个容器或范围(如数组、std::vector
等 它提供一系列可遍历的元素。) ,
使用示例
假设我们有一个 std::vector
容器,可以通过基于范围的 for
循环来遍历数组中的每个元素:
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
// 使用基于范围的 for 循环遍历
for (int v : vec) {
std::cout << v << " "; // 输出:1 2 3 4 5
}
return 0;
}
在这个例子中,int v
表示 vec
中的每个元素,而 vec
是要遍历的容器。
遍历数组
基于范围的 for
循环同样适用于 C++ 的内置数组:
int arr[5] = {10, 20, 30, 40};
for (int v : arr) {
std::cout << v << " "; // 输出:10 20 30 40
}
TIP
建议使用 auto
让编译器自动推导类型,auto&
表示对元素的引用,减少手动编写类型声明的繁琐和可能的错误。
放下 C 语言余孽,拥抱 C++ 特性
ios::sync_with_stdio(0); cin.tie(0),; cout.tie(0);
别惦记你那 printf/scanf
啦,这三个语句可用于优化 C++
中 cin
和 cout
的输入输出性能,使得 C++
的 IO流
与 C 的 stdio
达到几乎一致的速度的同时,兼顾了 C++
一贯的稳定性。它们的作用分别如下:
ios::sync_with_stdio(false)
:- 这一语句用于禁用 C++ 的
iostream
与 C 语言的stdio
的同步。 - 默认情况下,C++ 的
cin/cout
与 C 语言的scanf/printf
是同步的,以确保它们可以混合使用。然而,这种同步操作会带来额外的性能开销。 - 设置
ios::sync_with_stdio(false)
可以提升cin
和cout
的输入输出效率,但一旦禁用了同步,cin/cout
和scanf/printf
不应混合使用,否则可能会出现输出顺序错乱或其他问题。
- 这一语句用于禁用 C++ 的
cin.tie(0)
:tie()
函数用于控制输入输出流之间的绑定关系。- 默认情况下,
cin
与cout
是绑定的,即每次使用cin
输入时,都会自动刷新cout
缓冲区,确保cout
输出的内容是最新的。 - 通过调用
cin.tie(0)
,可以解开这种绑定,使cin
和cout
之间的刷新机制解除,从而提升性能,尤其是在大量输入输出操作时。这样可以减少不必要的缓冲区刷新,从而提高运行速度。
cout.tie(0)
:- 与
cin.tie(0)
类似,这个语句用于解绑cout
与其他流(通常是cin
)的关系。
- 与
vector.emplace_back()
emplace_back
是 C++11 引入的std::vector
的成员函数。它的作用是在容器的末尾直接构造一个元素,而不是先创建一个对象再拷贝或移动到容器中。它的主要优势在于避免不必要的拷贝或移动操作,提高效率。emplace_back
直接在容器的内存空间中构造元素。相比于push_back
,它避免了创建临时对象的开销。适用于构造复杂对象或自定义类型对象的场景,因为可以传递构造对象所需的参数。- 对于自定义类型,
emplace_back
也非常有用,因为它可以直接传递构造函数的参数:
Lambda 表达式
Lambda 表达式是一种用于定义匿名函数的方式,可以在局部范围内创建一个没有名称的函数对象。它的基本语法如下:
[capture](parameters) -> return_type { body }
[capture]
:捕获列表,用于指定 lambda 表达式中可以使用的外部变量。特别地,&
表示按引用捕获外部作用域中的所有变量。(parameters)
:参数列表,类似于普通函数的参数列表。-> return_type
:返回类型,可以省略,编译器会自动推导。{ body }
:函数体,包含 lambda 表达式的代码。
使用
可选地,在 lambda 表达式后面的
()
表示对这个 lambda 表达式的调用。相当于直接执行这个匿名函数。如果 lambda 表达式没有立即被调用,你可以将其存储在一个变量中,并在稍后的代码中根据需要多次调用。这种方式在 C++ 中非常灵活,可以用于多种场景,比如延迟执行、回调函数、函数对象等。下面是一些使用方法:
1. 存储到变量中并调用
你可以将 lambda 表达式赋值给一个变量,然后在程序的其他地方调用它:
c++#include <iostream> int main() { // 将 lambda 表达式存储在变量中 auto printMessage = []() { std::cout << "Hello, World!" << std::endl; }; // 在后面需要的时候调用它 printMessage(); // 输出: Hello, World! printMessage(); // 可以多次调用 return 0; }
2. 作为函数参数
你可以将 lambda 表达式作为参数传递给另一个函数。
3. 返回值为 Lambda 表达式
你可以编写一个函数,返回一个 lambda 表达式供后续调用:
c++#include <iostream> auto createMultiplier(int factor) { return [factor](int x) { return x * factor; }; } int main() { auto doubleValue = createMultiplier(2); // 创建一个将值乘以2的 lambda auto tripleValue = createMultiplier(3); // 创建一个将值乘以3的 lambda std::cout << doubleValue(5) << std::endl; // 输出: 10 std::cout << tripleValue(5) << std::endl; // 输出: 15 return 0; }