一些凌乱的小知识

1 可以使用下标操作的容器的下标引用

对容器的下标引用操作和我们对数组引用下标操作一样,千万不要去引用未定义的单元,否则你将..

以vector为例:

Code:
  1. vector<int> vec;   
  2. for (int i = 0; i < 5; ++i)   
  3. {   
  4.      vec[i] = 1;   
  5.  }  

 你不能这样做。因为根据vector的特性,我们定义的vec这个vector<int>类型变量目前没分配空间。我们的引用操作将会去引用为定义单元。引起内存错误。但我们若真要想这样为vec型变量赋值怎么办?

我们可以这样:

Code:
  1. vector<int> vec(10);   
  2. for (int i = 0; i < 10; ++i)   
  3. {   
  4.      vec[i] = 0;   
  5. }  

OK!You Can!因为此时vec变量已经有了10个int类型的内存空间。所以你可以对他进行引用。但此时我们仍然不可以利用赋值操作对下标为10及以后的单元进行引用。但我们可以使用cout来输出以后单元的内容,你样的引用不会出错。但若在第一种情况下我们使用cout来引用仍然出错。因为那时候vec根本没有内存单元,所以我们一切的下标引用都是错误的。而现在不一样了,虽然我们使用类似cout << vec[20] << endl;引用虽然已经出界,但它仍然指向已存在的内存单元,只不过是一个不在我们掌握范围内的内存单元罢了。但为什么我们不可以对这样的内存单元进行写操作呢?我想 一是因为我们没有对这样的单元有掌握权,即我们并没有想操作系统申请权限,二是因为操作系统的一个自我保护,若我们目前的下标操作指向了一个很重要的内存单元,若操作系统允许写操作,岂不是要出大问题了。呵呵。。

2 指针应注意的一些东西

若我们在程序别处已定义了一个类类型的指针,如:

Code:
  1. vector<int> *p = 0;  

 

我们在此处想判断一下指针所指向的对象中第二个数是否为1;

我们该如何做呢?

Code:
  1. if ((*p)[1] == 1)   
  2. {   
  3.      //do something   
  4. }  

这样做行吗?显然我们根据我们的目的直接写出了条件,但是我们还应该判断该指针所指的对象是否为空,否则它会影响我们的判断。甚至还有些对空对象对下标的引用会引起错误。如:vector;所以我们对于本题我们该这么些。

Code:
  1. if ( !p->empty() && (*p)[1] == 1)   
  2. {   
  3.         //do something;   
  4. }  

 然而这样够吗?我们还应该想到一点,那就是空指针,也就是我们定义成类似这个样子的指针:

Code:
  1. vector<int> *p = 0;  

对空指针的引用会不会出现问题呢。这个是可想而知了;故我们还应该对一层判断:

Code:
  1. if ( !p && !p->empty() && (*)p[1] == 1)   
  2. {   
  3.       //do something ..   
  4. }  

这样就应该OK,完美了吧。呵呵。。说实话其实我们仅仅用最后一个条件进行判断一般也不会出错,因为我们使用的一般都是定义过的,且有内容的变量。但那样的程序强壮性与可维护性都可差。不是嘛?

既然这里牵涉到了!p 的用法,我是有必要说一下在条件判断中!p 和 *p == 0的区别了:

 !p 是用来判断指针所指的对象是否为空,而*p 是来判断p所指的内容是否为0值。它们两个的区别在与:

① 对于所有类型的对象!p 均可以这样写出这样的形式,而*p == 0;就不一定了,它要看它所指的对象是否定义了== 这样的操作符重载,是否可以和 0 进行比较。

② 它们所进行的目的不同,一个是判断对象,一个是判断值,如:

Code:
  1. int *p =  0;   
  2. if (*p == 0)   
  3. {    
  4.      // do something...   
  5. }  

这样使用就会出错。正如我们上面所说的那样,我们还应加上一个 !p 的条件更合理。看下面情况:

Code:
  1. int value = 6;       
  2. int *p = &value;       
  3. if ( !p )       
  4. {       
  5.      //do something....       
  6. }    

对于此例我们的目的若是想判断p所指向的值是否为0,那我们可惨了,条件永远满足,即使你修改过p所指向的值后再判断,条件依然满足。上面我们的行为是在判断是真所指向的对象是否是空对象。显然不是,故条件永远成立。若不知道这点的话,那我们的调试功夫可得多下一翻了。。呵呵。。

3 一些控制符

setfill(c) 设置填充字符

setw(t)  设置字符宽度,若宽度小于所设置的宽度,左补空格,若大于,则原样输出.

setprecision(n) 设置有效数字

setbase(int _Base);

If _Base is 8, then mask is ios_base::oct.

  • If _Base is 10, then mask is ios_base::dec.

  • If _Base is 16, then mask is ios_base::hex.

  • If _Base is any other value, then mask is ios_base::fmtflags(0).

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值