常见误区
前言
目前 OI 界有许多谣言,有些很扯淡但是有人信。。。
所以我想写一篇博客来纠正一部分。
如果我的观点也有错误,请指正;也欢迎补充一下。
正文
语言本身
- 关于 C++ 是弱类型语言还是强类型语言,网上说法颇多。武断地说是强类型语言是不合适的。
卡常
register
其实没有什么用,目前已经被移除。值得一提的是,即使写了register
也不一定会放在寄存器内。不要认为你比编译器聪明,编译器比你更懂优化。- 无谓的位运算也完全没有意义。例如,在快读中的
x*10+c-'0'
,如果写成(x<<3)+(x<<1)+(c^'0')
几乎完全没有优化,甚至有时会负优化。不要认为你比编译器聪明,编译器比你更懂优化。 inline
其实也没很大作用。写上inline
准确的说,只是你建议编译器内联,而非要求。编译器可以选择不鸟你。而且,如果你对一个巨大长的函数内联,反而会有负优化。
库函数和 STL 误区
pow/sqrt/exp/log
等函数是理论 \(O(1)\) 的,只是常数比较大或者精度掉渣。memset
和strlen
等是小常数 \(O(n)\),非必要慎用。stack/queue
内部实际是依靠deque
实现的,空间常数其实很大。- 不要神秘地鄙视
cin/cout
,关同步流后cin/cout
速度和scanf/printf
是一个量级的。 - STL 几乎用的都是左闭右开区间。例如
.end()
指向的是最后一个元素位置的下一个位置。 __builtin_popcount
等函数复杂度都是 \(O(1)\),且适用于unsigned int
类型,若是long long
请用__builtin_popcountll
等。- STL 容器的
.size()
的返回值是unsigned
类型,i<s.size()-1
在s
恰好为空时会挂掉。但是形如for(int i=s.size()-1;~i;i--)
则不会挂。
杂项
#define int long long
有说法认为是 ub。不过无论如何,这样会拉大空间时间的常数,风险较大。- 逗号表达式从左到右运算。
printf
输出浮点数,无论是单精度还是双精度都应该使用%f
输出。