理解数组

什么是数组? 简单来说数组代表一块连续的内存,内部包含连续的一排相同的对象, 因为内存分布连续且对象大小相同,所以我们可以高效的根据索引随机访问和赋值。

数组是我们平时用的最多的数据结构, 因为它很符合我们程序运行时的平坦内存布局,使用起来简单而高效。可以这样说,只要恰当的使用,数组可以满足我们工作中的大部分需要。

数组包括静态数组和动态数组, C/C++语言内置支持数组, 我们平时一般这样用:
void  test()
{
    
int  ar[ 5 =  { 1 2 3 4 5 };
    
int  v  =  a[ 2 ];

    
int *  pAr  =   new   int [ 3 ];
    pAr[
1 =  v;
    delete []pAar;
}

其中ar是静态数组,它分配在该线程的堆栈上, 而pAr是动态分配的,它内存分配在堆上, 详细内存分配可以看我这篇 《C++中new和delete的背后》

对于数组,我们要注意的是C++数组不支持多态, 这里他们讨论过这个问题 《C++的数组不支持多态?》

上面我们讨论的动态数组是C++语言内置支持的, 但是因为内置数组大小固定且容易越界, 另外还有上面的多态问题, C++标准库为我们提供了另一种封装vector, 我们可以这样用:
void  test()
{
    vector
< int >  ar;
    ar.push_back(
1 );
    ar.push_back(
2 );
    
int  d  =  ar[ 1 ];
    ar[
2 =   10 ;
}

我们可以看到, vector使用起来非常方便, 一方面我们可以像内置数组一样使用, 另一方面我们不用再担心容量问题, 因为它会在大小不够时自动增加。

vector虽然简单,但是实际上它有 不少陷井和技巧, 下面列举一些常见问题:

1。小心迭代器失效
void  test()
{
 vector
< int >  ar;
 ar.push_back(
1 );
 vector
< int > ::iterator itr  =  ar.begin();
 
for ( int  i = 0 ; i < 100 ++ i)
 {
  ar.push_back(i);
 }
 
 
int  d  =   * itr;
}

你看出上面代码的问题了吗? 
不错, 可能在我们push_back过程中, 内存重新分配了, 导致我们原先记录的迭代器itr已经失效, 后面再重新访问就出错了。

2。防止内存 多次 分配
我们知道在push_back过程中, 当数组容量不够时, 我们就会重新分配内存, 然后将已有的元素进行拷贝, 效率很低。
所以最好的方法是用reserve()方法对需要的大小进行正确的估计,然后预留足够的空间, 防止重新内存分配。

3。释放已分配空间
有些时候某个vector对象已经分配了挺大空间,当用的差不多时, 我们需要释放这些空间, 但是要保留该对象,要怎么做?
这里有个挺实用的swap技巧:
vector < int >  vec;
void  test()
{
    
for ( int  i = 0 ; i < 10000 ++ i)
        vec.push_back(i);


    vector
< int >  temp;
    vec.swap(temp);
}

4。删除某些符合条件的元素
void  test()
{
 vector
< int >  ar;
 
for ( int  i = 0 ; i < 100 ++ i)
 {
  ar.push_back(i);
 }

vector
< int > ::iterator itr  =  ar.begin();
 
for (;itr  !=  ar.end();)
 {
  
if ( * itr  >   10 )
  {
   itr 
=  ar.erase(itr);
  }
  
else
  {
   
++ itr;
  }
 }
}

上面的代码删除数组中大于10的所有item, 实际上我们可以下面更简单的方法替代:
ar.erase(remove_if(ar.begin(), ar.end(), bind2nd(greater < int > (),  10 )), ar.end());

从上面的一些技巧,我们可以看到, 只有真正理解了vector的内部实现原理, 我们才能规避一些使用陷井, 更简单而高效的开发程序。

上面我们讨论的vector主要针对的模拟C++内置的动态数组部分, 而对于静态数组部分,我们是不是也有相应的类? 
是的,C++11里新增的array就是做这个事的, 我们可以这样用:
void  test()
{
 std::array
< int 10 >  ar  =  { 1 2 3 4 }; 
 ar[
5 =   33 ;
}

其中array<int, 10>在内部存储实际上是int data[10];

最后, 简单总结下,我们从C++的内置数组讲到标准库提供的vector, 最后谈到C++11新增的array, 数组这个最基本的数据结构在C++中终于有了完整的支持。

转载于:https://www.cnblogs.com/weiym/p/3724364.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值