查漏补缺,巩固基础——C++Primer之旅day4

来源:互联网 发布:吉林省中小学网络研修 编辑:程序博客网 时间:2024/05/18 14:26
数组和指针
数组元素初始化
        如果没有显式提供元素初值,则数组元素会像普通变量一样初始化:
1、在函数体外定义的内置类型数组,其元素均初始化为0;
2、在函数体内定义的内置类型数组,其元素无初始化;
3、如果数组元素为类类型,怎不管在哪里定义,都自动调用该类的默认构造函数进行初始化;若该类没有默认构造函数,则必须为该数组的元素提供显示初始化。

计算数组的超出末端指针
        vector类型提供的end操作将返回指向超出vector末端位置的一个迭代器,这个迭代器常用作哨兵,来控制处理vector中元素的循环(划定容器的界限)。类似的,也可计算数组超出末端指针的值:

const  size_t  arr_size  =  5;
int  arr[arr_size]  =  {1,2,3,4,5};
int  *p  =  arr;
int  *p2  =  p  +  arr_size;

        本例中指针p指向数组arr的第一个元素,p2指向数组末端元素的下一个位置。在C++中,允许计算数组或对象的超出末端的地址,但不允许对该地址进行解引用操作。

typedef的用法
1、直观简洁
        用在旧的C代码中,帮助struct。以前的代码中,声明struct新对象时,必须要带上struct,即形式为: struct 结构名对象名,如:
struct  tagPOINT  {
    int x;
    int y;
}; 
struct   tagPOINT  p1;
而在C++中,使用typedef:
typedef  struct  tagPOINT  {
    int x;
    int y;
}POINT;

POINT p2; // 这样就比原来的方式少写了一个struct,比较省事,尤其在大量使用的时候
     
2、代码的可移植性  
        假如在32位机器上,我们用int定义了(许多)变量,当把代码移植到16位机器时,int就达不到我们对数据长度的要求,如果一一修改,工作量十分大,并且容易出现错误。使用typedef定义数据类型的别名,例如:typedef  int  size_t,然后使用size_t来定义变量,当代码移植到其他机器上时,只需修改typedef定义即可。

3、隐藏复杂类型
        typedef 还可以掩饰复合类型,如指针和数组。例如,你不用像下面这样重复定义有 81 个字符元素的数组:
[cpp]
char  line[81];
        定义一个 typedef,每当要用到相同类型和大小的数组时,可以这样:
[cpp] 
typedef  char  Line[81]; 

此时Line类型即代表了具有81个元素的字符数组,使用方法如下:
[cpp]
Line text, secondline;
        同样,可以象下面这样隐藏指针语法:
[cpp]
typedef char * pstr;
int mystrcmp(pstr, pstr); 

这里将带我们到达第一个 typedef 陷阱。标准函数 strcmp()有两个"const char * "(指向常字符串的指针)类型的参数。因此,它可能会误导人们象下面这样声明 mystrcmp():
[cpp]
int mystrcmp(const pstr, const pstr); 

用GNU的gcc和g++编译器,是会出现警告的,按照顺序,"const pstr"被解释为"char* const"(一个指向 char 的指针常量),两者表达的并非同一意思。为了得到正确的类型,应当如下声明:
[cpp]
typedef  const char*  pstr;

动态数组
        普通数组变量通过制定类型、数组名和维数来定义。而动态分配数组时,只需指定类型和数组长度,不必为数组对像命名:
int  *pia  =  new  int[10];
此new表达式分配了一个含有10个int类型元素的数组,并返回指向该数组第一个元素的指针。
        对于动态分配的数组,其元素只能初始化为元素类型的默认值,而不能像普通数组变量一样,用初始化列表为数组元素提供不同的值。动态分配数组时,如果数组元素具有类类型,则使用该类的默认构造函数;如果数组元素师内置类型,则无初始化:

string  *psa  =  new  string[10];   //初始化为长度为10的空string
int  *pia  =  new  int[10];//无初始化
        也可使用跟在数组长度后面的一对空圆括号,对其初始化:
int  *pia2  =  new  int[10] ();//初始化为10个0

允许动态分配空数组
        之所以要动态分配数组,往往是由于编译时并不知道数组的长度。我们可以编写如下代码:
size_t  n  =  get_size();
int  *p  =  new  int[n];
先计算数组长度,然后创建数组。
        有趣的是,如果get_size()返回0会怎么样?答案是:代码仍然正确。C++虽然不允许定义长度为0的普通数组,但明确指出,调用new动态创建长度为0的数组时合法的:
char  arr[0];//error
char  *cp  =  new  char[0];//ok        

用new创建长度为0的数组时,new返回有效的非零指针,该指针与new返回的其他指针不同,不能进行解引用操作(不指向任何元素),但可以进行比较运算(for循环);在该指针上加(减)0,;或者减去本身,得0值。

动态空间的释放
int  *pia  =  new  int [10];
delete  [ ] pia;
注意,new和delete必须成对使用。

0 0