C/C++ 知识点补充
C/C++的那些小知识点
“Short-Circuit” Evaluation
在进行逻辑运算时,如果表达式已经能够确定最终值时,不再继续进行计算.
这减少了一定的计算量并且避免了错误的访问和计算.
bool a = true,b;
int c = 0;
b = a || ++c > 0;
printf("%d %d\n",b,c);
输出将会是1 0
,因为a
已经是true
了,故而进行短路,不再往后执行,不执行++c
.
这一特性可以用在如下场景来避免除0引发错误:
int a,b;
scanf("%d%d",&a,&b);
if(b != 0 && a % b == 0)
printf("%d is a multiple of %d", a, b);
else
printf("Something wrong.");
Lambda Expression
Lambda 表达式在很多其他语言中都有过使用了,如python
中的func = lambda x: x + 2
,又或者在JavaScript
中的let func = (a) => a + 2;
,甚至在C#
中见到的Func<int,int> add = a => a + 2;
都是Lambda 表达式.它在这些语言中都有自己的位置,这也侧面展现出它的重要,于是在C++11
的标准中,C++
也支持了Lambda 表达式.
Lambda 表达式表示的是一种匿名的函数,有时一个极其简单的函数(甚至不配拥有姓名)或者是一个作为参数传递的函数,当给它单独起名字不方便或者使用上遇到一些不确定性,Lambda 表达式就派上了用场.它的确是个函数,只是不配拥有姓名.
这里有几个递归函数的例子:
auto gcd = [&](long a, long b) -> long { return a % b == 0 ? b : gcd(b, a % b); };
auto Fibonacci = [&](int a) -> long long { return (a == 1 || a == 2) ? 1 : Fibonacci(a - 1) + Fibonacci(a - 2); };
auto Factorial = [&](int a) -> long long { return (a == 1) ? 1 : Factorial(a - 1) * a; };
在最新的C++20
标准中Lambda 表达式的基本形式可以写为:
[ captures ] < tparams > ( params ) specifiers exception attr -> ret requires { body }
或者简写为:
[ captures ] ( params ) -> ret { body }
captures
:捕获列表。前面的例子中[&]
表示按引用捕获,还可以是[=]
按值捕获。tparams
: 类型参数。在最新的C++20
标准中添加。params
:和普通函数一样的参数。specifiers
:只有这个Lambda 表达式是mutable
的才允许修改按值捕获的参数。exception
:异常标识。attr
:属性标识。初学者暂时不必理解。ret
:返回值类型,可以省略,让编译器通过 return 语句自动推导。requires
: 向闭包类型的operator()
添加制约。初学者暂时不必理解。body
:函数的具体逻辑。
此处相关细节内容从略,可参考如下页面:
现代 C++:Lambda 表达式
Lambda 表达式
Lambda expressions
C++ Multithreading
在C++11
的更新中还有一个引人注目的地方在于关于多线程的更新,让利用C++
编写多线程应用变得十分容易.(当时不知道我真的是孤陋寡闻)
本想着直接操作线程,在寻寻觅觅了<thread>
和<future>
之后,发现std::async
提供的功能让任何人都可以十分容易的实现基础的多线程功能.
对于多线程的含义、意义、future
和promise
的关系及其实现原理等等的详细问题这里先从略,读者若好奇建议自行查阅,这里只做简单使用层面的说明和记录.
//设 func 是以 args 为参数返回值为 vector<int> 的函数
int thread_count = 16;
vector<std::future<int>> futures;//存放 future 对象
vector<int> result;
for (int i = 0; i < thread_count; ++i)
futures.push_back(std::async(std::launch::async,func,args));//创建线程
for (int i = 0; i < thread_count; ++i)
{
vector<int> part_result = futures[i].get();//等待线程并获取结果
result.insert(result.end(), part_result.begin(), part_result.end());
}