CPP {特殊知识汇总}
#cout<< i<< ","[i == N-1];
老六语法。。。#
看jly代码: FOR_( i, 0, 3){ cout<< i<< ","[i == 3];}
, 她的效果是0,1,2,3
(即末尾不会有,
);
刚开始还以为是 C++新语法糖… 其实是字符串数组的下标操作, 对于","
她是个字符串数组 其[0] = ','
而[1] = '\0'(结束符)
, 因此 对于<3
此时i==3 为 0
因此输出,
, 到这里3
时 此时输出\0
(其实'\0'
她并不会输出! 因为她是控制字符 其实她会中止掉整个cout
的输出!;
cout<< 1<< '\0'<< 2<< endl;
cout<< 3<< '\0'<< 4<< endl;
答案只会输出`1`, 不会输出`2,3,4`, 因为一旦遇到`\0`, 你可以输出 输出流就关闭了;
@DELI;
#下标越界是合法的…#
@LINK: (https://editor.csdn.net/md/?articleId=128696165)-(@LOC_1)
;
@DELI;
#重視程序的警告#
如果int a;
沒有賦初值 此後也沒有使用過他, 那麼程序會有個警告 unused
;
一旦有警告 就可能發生你意想不到的事情; 比如此時 這個a
此時會被編譯器給清除掉, 即這個變量在最終的exe裡 是不存在的!
@DELI;
#基础类型的效率非常高#
class Double{
doubel x;
constexpr Double( doubel x) : x(x){}
};
这种方式(即类) 比起 using Double = double
这种方式, 比如对于Dfs( Double x)
递归 要慢4
倍! 换句话说, 基础类型他的构造/拷贝 要远远优于 你的自定义类型;
因此, 要尽可能的使用 基础类型;
对于引用 没必要对(基础类型)使用, 即const double &
是多此一举的;
@DELI;
#end()
迭代器#
只要看到end()
迭代器 (不管是vector/ set/ map/ unordered_set/...
) 他的本质 是一脉相承的; 你应该这样想象他: 如果你容器里的个数是x
个 那么实际上 真实的元素个数是x+1
个, 一开始容器为空 其实不是空的 因为有个哨兵 即end()
;
因此, 你把他想象成: 从任意迭代器进行std::next
的ForwardIterator
移动 他最终一定会到达end()
;
比如说 对于双向迭代器Bidirectional
(vector, set, map
) 你应该想象成是begin() <-> b <-> c <-> end()
; (这个图非常非常重要, 也就是迭代器个数 = 元素个数 + 1
, 迭代器之间的移动 不仅是元素之间的 还包括end()
)
也就是 不要以为元素可以进行移动, 其实end()
也可以移动; 你从end()
进行prev()
移动 就可以到达c
, 同样你从c
进行next()
就可以到达end()
;
再比如 对于前向迭代器Forward
(unordered_?
) 你应该想象成begin() -> b -> c -> end()
;
总之, 如果从迭代器移动结构图的角度看, 他里面是有元素个数 + 1的节点, 多出来的一个 就是end()
; 因此从迭代器移动的角度看: end()
与一般元素的迭代器, 享有同等地位;
但要注意, end()
的作用 就是出现在这个迭代器移动里, 你不可以把他当做是一般元素, 比如*end()
这个取值操作 会爆错误;
向后移动的终点 一定是end()
, 向前移动的终点 一定是begin()
;
@DELI;
#迭代器的移动#
不管是{前向/双向}迭代器:
向后移动std::next
时, 一旦移动到end()
时, 你必须停止! 再移动就出界了(会出错的)! 这点 你需要自己去判断, 即当你调用std::next( x)
时 要加个if( x != S.end())
的判断, 即如果不是end()
才可以调用next()
(系统不会帮你判断, 因为std::next
是全局函数, 他得不到S.end()
);
同样的, 向前移动std::prev
时, 一旦移动到begin()
时, 你必须停止 再移动就出界了(会出错的)! 即如果x != S.begin()
才可以进行std::prev
(因为他是全局函数 他也得不到S.begin()
所以这个工作 只能自己做);
@DELI;
#for( auto i : A)
也可适用于数组#
T arr[ 5] = {...};
for( auto i : arr){}
这是可以的, 也就是 arr
不仅可以是容器, 是个数组也可以;
@DELI;
#lower_bound
与find
的区别#
对于set
容器;
auto iter = s.lower_bound( 4)
是找到
≥
4
\geq 4
≥4的第一个元素的迭代器; (如果没有返回end()
)
.
也就是*iter
不一定就是
4
4
4;
auto iter = s.find( 4)
是找到
=
4
= 4
=4元素的迭代器; (如果没有返回end()
)
.
也就是*iter
一定就是
4
4
4; (如果不为end()
的话)
@DELI;
#begin(), end()
与 front(), back()
#
begin(), end()
返回的是: 迭代器 (抽象为指针) (根据情况, 迭代器可能是const
的);
.
begin()
是首元素的迭代器, end
是末元素的下个位置的迭代器;
.
*begin() = xx
即赋值操作;
front(), back()
返回的是: 元素引用 (根据情况, 迭代器可能是const
的);
.
front()
是首元素的引用, back
是末元素的引用 (这一点, back
与end
是不同的);
.
front() = xx
是赋值操作;
@DELI;