STL

iterator 的小东西

Posted on

被C++的迭代器给坑了2个小时

不得不立文警告自己

C++的iterator 对于不同的STL来说 有不同的操作 小小的总结一下

(1)所有迭代器
p++ 后置自增迭代器
++p 前置自增迭代器
(2)输入迭代器
*p 复引用迭代器,作为右值
p=p1 将一个迭代器赋给另一个迭代器
p==p1 比较迭代器的相等性
p!=p1 比较迭代器的不等性
(3)输出迭代器
*p 复引用迭代器,作为左值
p=p1 将一个迭代器赋给另一个迭代器
(4)正向迭代器
提供输入输出迭代器的所有功能
(5)双向迭代器
--p 前置自减迭代器
p-- 后置自减迭代器
(6)随机迭代器
p+=i 将迭代器递增i位
p-=i 将迭代器递减i位
p+i 在p位加i位后的迭代器
p-i 在p位减i位后的迭代器
p[i] 返回p位元素偏离i位的元素引用
p < p1 如果迭代器p的位置在p1前,返回true,否则返回false
p <= p1 p的位置在p1的前面或同一位置时返回true,否则返回false
p>p1 如果迭代器p的位置在p1后,返回true,否则返回false
p>=p1 p的位置在p1的后面或同一位置时返回true,否则返回false

其中对于我们比较常用的STL 的迭代器中

list set map 的迭代器 为 双向迭代器

vector string deque 为的迭代器 随机迭代器

queue stack 不支持迭代器

输入输出迭代器分别前置一个 istream_ ostream_

另外加了 cost 的迭代器和字面意思一样 不得访问其他数据

C

setjmp 与 longjmp

Posted on

最近看到C看到一个很让人费解的函数组合 setjmp 和 longjmp 使用方法还是比较简单的
setjmp设置跳跃点 longjmp表示跳跃

具体的操作如下
首先定义一个 唯一的标志性 flag jmp_buf变量
再加上 函数申明 int setjmp(jmp_buf env); void longjmp(jmp_buf env, int value);
当设置 jmp 即第一次执行 setjmp时 函数的返回值都为 0
通过longjmp 跳跃至相同jmp_buf 的setjmp函数里并执行 set_jmp的返回值将变成 long_jmp设置的 value
理解起来后发现实际上是跟 goto 差不多的 但long_jmp 跳得更远一些 goto只限于同一函数内 long_jmp无限制 包括文件

附个代码理解一下

#include <stdio.h>
#include <setjmp.h>
jmp_buf buf;
void haha()
{
    printf("in haha()\n");
    longjmp(buf,1);
    printf("kaonima\n");
}
int tim=0;

int main()
{
    if(setjmp(buf))
    {
        printf("back in main\n");
        tim++;
    }
    else
    {
        printf("first time through\n");
        haha();
    }
    if(tim<3) longjmp(buf,1);
    return 0;
}

结果是

first time through
in haha()
back in main
back in main
back in main

另外 这两个函数一般来说 可用于C中的异常处理

顺便贴个wiki的 告诫 (太专业 也不是很明白……)

longjmp实现了非本地跳转,微软的IA32程序设计环境中正常的"栈卷回"("stack unwinding")因而没有发生,所以诸如栈中已定义的局部变量的析构函数的调用(用于销毁该局部变量)都没有执行。所有依赖于栈卷回调用析构函数所做的扫尾工作,如关闭文件、释放堆内存块等都没有做。但在微软的X64程序设计环境,longjmp启动了正常的"栈卷回"。
如果setjmp所在的函数已经调用返回了,那么longjmp使用该处setjmp所填写的对应jmp_buf缓冲区将不再有效。这是因为longjmp所要返回的"栈帧"(stack frame)已经不再存在了,程序返回到一个不再存在的执行点,很可能覆盖或者弄坏程序栈

值得深究一下的是 jmp_buf 变量在这里立个flag 吧 以后会来补充