C++ primer之第三章(iterator,arry)

iterator知识点:
        end()函数返回容器对象的尾部元素的下一个位置。没什么实际意义,表示我们对所有元素处理完了。
        const_iterator类似常量指针,表示指向的内容不能变,只能读,而const iterator表示指针常量,指向的地址不能变。
        C++11标准中,添加了两个迭代器的新函数 cbegin()&cend(), 为了便于专门得到const_iterator类型返回值。

习题:
        3.24之前就采用的迭代器做的,所以在这里不做了。
        3.26
        答:为什么采用 mid=beg+(end-beg)/2,而不用mid=(beg+end)/2?
                首先第一种写法与第二种数学上得到的结果是完全一样的,这个可以通过取整函数的方法证明。但是beg+end操作很可能会出现溢出              的风险,但是后一种写法不会出现比end要大的中间数据,所以比较安全。 2你要是看c++stl源码就会发现用的也是第二种,因为考虑 了              通用性,用第一种如果beg和end是指针或者迭代器的话是无法编译通过的,因为指针和迭代器运算不支持相加运算,却支持相减运算,                 第二种相 当于相加了他们之间的距离,所以第二种通用性强。(迭代器的话要求是随机访问迭代器random access iterator)。

程序题:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
//减输出的单词变为大写采用迭代器
void fun3_22()
{
     vector <string> vec;
     string word;
     cout<< "请输入单词:" <<endl;
      while (cin>>word)
     {
           vec.push_back(word);
     }
      for ( auto it=vec.begin(); it!=vec.end(); ++it)
     {
            for ( auto ib=(*it).begin(); ib!=(*it).end(); ++ib)
                *ib = toupper(*ib);
           cout<<*it;
     }
}
//输出vector数组元素的2倍
void fun3_23()
{
     vector< int > vec;
      int temp;
     cout<< "请输入数字:" <<endl;
      while (cin>>temp)
     {
           vec.push_back(temp);
     }
      for ( auto it=vec.begin(); it!=vec.end(); ++it)
     {
           cout<<2*(*it);
     }
}
//用迭代器实现成绩分段统计
void fun3_25()
{
     vector< int > vec;
     vector< int > num(10,0); //vs2010不支持列表初始化
      int grad;
     cout<< "请输入成绩:" <<endl;
      while (cin>>grad)
     {
           vec.push_back(grad);
     }
      //实现分段统计
      for ( auto it=vec.begin(); it!=vec.end(); ++it)
     {
            //++num[(*it)/10];
           ++*(num.begin()+(*it)/10);
     }
      for ( auto it=num.begin(); it!=num.end(); ++it)
           cout<<*it<<endl;
}
int main()
{
      //fun3_22();
      //fun3_23();
     fun3_25();
      return 0;
}

关于数组的知识点:
        1.定义数组的时候必须指定数组的类型,不允许用auto关键字由初始值的列表推断类型。另外和vector一样,数组的元素应为对象, 因此不存在引用的数组
        2.字符串数组可以采用字符串字面值的初始化形式。当使用这种方式是一定要注意字符串字面值的结尾处还有一个空字符,该字符也会被拷贝到字符数组中去。
      char a1[] = { 'a' , 'b' , 'c' };     //没有空字符
      char a2[] = { 'a' , 'b' , 'c' , '\0' }; //初始化显示添加空字符
      char a3[] = "abc" ;                 //自动隐式添加空字符
      char a4[4] = "abcd" ;          //没有空间存放
        3.数组的内容不能拷贝,也无法使用一个数组直接初始化另一个数组(a1=a); 一些非标准的编译器拓展功能支持此种拷贝,初始化,但是这种非标准不要使用。
        4.理解数组复杂声明的方法:从数组的名字开始,按照由内到外顺序阅读。
        5.size_t是一种机器相关的无符号类型。它被设计的足够大,可以表示任意对象的数量。
        6.数组的维度必须要是常量的,而且必须是编译时确定的,不是分配是确定的。如下:
      int len;
     cout<< "请输入数组的长度:" <<endl;
     cin>>len;
      const int i = len;
      int a[i];  //错误,运行时 确定
      const int j = 5;
      int b[j]; //正确
        7.auto根据值来推断类型,decltype根据变量类型来推断类型。
        8.与string,vector类型不一样的是,内置类型如数组的下标不是无符号类型,即也可以为负数。
        9.用关键字using作为别名声明的开始,其后紧跟别名和等号,其作用是把等号左侧的名字规定  成等号右侧类型的别名,如 : using int_array = int [ 4 ];int_array替代匿名int[4]数组。
        10.size_t是cstddef头文件中定义的一种与机器实现有关的无符号整数类型,它的空间足够大,能表示任意数组大小, size_t和size_type是什么类型取决于编译器。都用size_t一般来说也没什么问题,因为在通常的实现里这俩是同一个类型。STL使用的是size_type(迭代器),其迭起器内部由size_t实现。
习题:
3.27 答:a错误非常量,b正确,c错误,因为c的维度是函数返回值,有可能是负数。d错误,空间不够。
3.29 答:数组不能动态变化,数组之间不能赋值。
3.30 答:下标越界。
3.33 答:不初始化,既没有分配内存,范围for循环无法执行。
3.34 答:P2-P1越界时,非法。
3.37 答:输出hallo,但此时*p继续有效,后面的为乱码。
3.38 答:没有意义相加,编译器不允许。
程序题:
#include <iostream>
#include <string>
#include <vector>
#include <cstring>
using namespace std;
//编写数组,数组的值就是下标的值
void fun3_31()
{
      int arr[10];
      for ( int i=0; i<10; ++i)
     {
           arr[i] = i;
           cout<<arr[i]<< "   " ;
     }
}
//实现数组拷贝
void fun3_32()
{
      int arr[10];
      for ( int i=0; i<10; ++i)
     {
           arr[i] = i;
     }
      int brr[10];
      for ( int i=0; i<10; ++i)
     {
           brr[i] = arr[i];
           cout<<brr[i]<<endl;
     }
}
//vector拷贝
void fun3_32(string cs)
{
     cout<<cs<<endl;
      int num;
     vector< int > vec,vec2;
     cout<< "请输入数字:" <<endl;
      while (cin>>num)
     {
           vec.push_back(num);
     }
     vec2 = vec;
      for ( auto it=vec2.begin(); it!=vec2.end(); ++it)
     {
           cout<<*it;
     }
}
//利用指针将数组元素置0
void fun3_35()
{
      int a[10];
      int *p = a;
     *p = 0;
      for ( int i=0; i<10; ++i)
     {
           a[i] = *p;
           cout<<a[i];
     }
     
}
//判断连个数组是否相等
void fun3_36()
{
      int pc = 0;
      int arr[5] = {1,2,3,4,5};
      int arr1[5] = {2,4,6,8,9};
      int arr2[5] = {1,2,3,4,5};
      if ( sizeof (arr)== sizeof (arr2))
     {
            for ( int i=0; i<5; ++i)
           {
                 if (arr[i]==arr2[i])
                ++pc;
           }
            if (pc==5)
                cout<< "相等" <<endl;
            else
                cout<< "不等" <<endl;
     }
     vector< int > vec,vec1;
      //vector<int> vec1 = {0, 1, 2}; vs2010不支持新标准
      for ( int i =0; i<3; ++i)
     {
           vec.push_back(i);
           vec.push_back(++i);
     }
      if (vec==vec1)
           cout<< "vector " << "相等" ;
      else
           cout<< "vector " << "不相等" ;
}
//比较string类型与比较 char[]类型
void fun3_39()
{
     string str = "Linux" ;
     string str1 = "Windows" ;
      if (str == str1)
           cout<< "相等" <<endl;
      else if (str > str1)
           cout<< "windows大" <<endl;
      else
           cout<< "Linux大" <<endl;
      char arr[] = "jdja" ;
      char arr1[] = "brbn" ;
      int result = strcmp(arr,arr1);
      if (result == 0)
           cout<< "一样大" ;
      else if (result == 1)
           cout<< "前者大" ;
      else
           cout<< "后者大" ;
}
//C字符串之间的拼接
void fun3_40()
{
      char ar[] = "Love has no" ;
      char br[] = "boundaries" ;
      //const int st = strlen(ar)+strlen(" ")+strlen(br)+1; //又是不支持,等过段时间换编译器
      char cr[30];
     strcpy(cr,ar);
     strcat(cr, " " );
     strcat(cr,br);
     cout<<cr;
}
//用整形数组初始vector对象
void fun3_41()
{
      int arr[8] = {1,2,3,4,5,6,7};
     vector < int > vec(arr,arr+7);
      for ( auto it=vec.begin(); it!=vec.end(); ++it)
           cout<<*it;
}
//用vector 初始化数组
void fun3_42()
{
     vector < int > vec(10,1);
      int arr[10];
      for ( int i=0; i<10; ++i)
     {
           arr[i] = vec.at(i);
           cout<<arr[i];
     }
}
void fun3_43()
{
      int ia[3][4] = {1,3,5,7,9,2,4,6,8,10,11,12};
   /*  
     for (const int(&p)[4] : ia)
        for (int q : p) cout << q << " ";
    cout << endl;
     */
      for ( int i=0; i<3; ++i)
            for ( int j=0; j<4; ++j)
                cout<<ia[i][j]<<endl;
      //这个比较麻烦
      /*for(int (*p)[4]=ia; p!=ia+3; ++p)
           for(int *q=*p; q!=*p+4; ++q)
                cout<<*q<<endl;
     */
      for ( auto p=ia; p<ia+3; ++p)
            for ( auto q=*p; q<*p+4; ++q)
                cout<<*q<<endl;
     
}
int main()
{
      //fun3_31();
      //fun3_32();
      //fun3_32("vector实现");
      //fun3_35();
      //fun3_36();
      //fun3_39();
      //fun3_40();
      //fun3_41();
      //fun3_42();
     fun3_43();
      return 0;
}










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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值