C++ 小知识点
尽量不使用 vector<bool> ——历史遗留问题
vector<bool> 不是一个通常意义上的vector容器。因为在 C++98 的时候,就有 vector<bool> 这个类型了,但是因为当时为了考虑到节省空间,所以 vector<bool> 使用了内部的中间存储结构,使得 bool 的存储单位最终被优化成了 bit ,但是在一些 vector 的操作中它会返回其存储的内部中间数据结构而不是我们期望的 bool 类型,从而导致错误!
GCC 内建函数
__builtin_
开头的这些函数是编译器的内建函数,由编译器自己来决定这个函数应该生成什么汇编代码(直接匹配粘贴), 所以移植性低,但是编译器往往通过指令实现它,所以更加高效。__builtin_popcount(int n)
精确计算 n 的二进制表示中有多少个 ‘1’。__builtin_clz(int n)
计算二进制前导零数目。
C可变参数
void func(int, ...) ...表示可变参数。其可以传递一个不同类型的值,在函数内通过前面的确定参数来推测(程序员推测);也可以传递 N 个值,再通过 stdarg.h 中的宏 va_list、va_start、va_arg、va_end 进行存储、初始化、读取、清理等操作,注意同样需要程序员自己判断什么时候读取结束(即程序自己不知道可变参数何时停止,故常常确定参数的最后一个是描述可变参数的长度)。
注意:正式如此 c/c++ 才要求函数参数是从右往左的顺序压入栈。否则(如果是从左往右压入栈的话)程序将无法找到左边的非可变参数(先压入栈的地址更大,栈地址从大往小增长)。
double average(int num,...) { va_list valist; double sum = 0.0; int i; //va_start第二个参数是确定参数的最后一个 va_start(valist, num); //程序员自己控制何时停止读取 for (i = 0; i < num; i++) { sum += va_arg(valist, int); } //清理为 valist 保留的内存 va_end(valist); return sum/num; }
extern "C" ——实现类C和C++的混合编程
在C++源文件中的语句前面加上
extern "C"
,表明它按照类C的编译和连接规约来编译和连接,而不是C++的编译的连接规约。这样在类C的代码中就可以调用C++的函数or变量等。注意,仍然要遵守C++的类型检测、参数转换规则。