Primer回顾 数组和指针
数组和指针类似于vector和迭代器。
区别在于:数组的长度是固定的.数组一经创建,就不允许添加新的元素.指针则可以像迭代器一样用于遍历和检查数组中的元素.
设计良好的程序只有在强调速度时才在类实现的内部使用数组和指针.
没有所有元素都是引用的数组.
1.在函数体外定义的内置数组,其元素均初始化为0;
2.在函数体内定义的内置数组,其元素无初始化;
不管数组在哪里定义,如果其元素为类类型,则自动调用该类的默认构造函数进行初始化;如果该类没有默认构造函数,则必须为该数组的元素提供显示初始化。
除非显示地提供元素初值,否者内置类型的局部数组的元素没有初始化。此时,除了给元素赋值外,其他使用这些元素的操作没有定义.
include "stdafx.h"
#include <iostream>
#include <string>
#include<bitset>
using namespace std;
int a[3];
int _tmain(int argc, _TCHAR* argv[])
{
cout<<a[1]<<endl;//输出0
int b[3];
cout<<b[1]<<endl;//输出一个乱七八糟的很大的负数
return 0;
}
特殊的字符数组:
初始化字符数组,1,既可以用一组由花括号括起来,逗号隔开的字符字面值进行初始化。2,也可以用一个字符串字面值进行初始化。注意:字符串字面值包含一个额外的空字符(null)用于结束字符串。当使用字符串字面值来初始化创建的新数组时候,将在新数组中假如空字符:
char ca1[]={'c','+','+'};
char ca2[]={'c','+','+','\0'};
char ca3[]="c++";
cout<<sizeof(ca1)/sizeof(ca1[1])<<endl;//3
cout<<sizeof(ca2)/sizeof(ca2[1])<<endl;//4
cout<<sizeof(ca3)/sizeof(ca3[1])<<endl;//4
const char ca3[6]=”Daniel”//错误,这里是有7个元素的.因为是字符串字面值.
注意不要用一个数组去给另外一个数组进行赋值操作
用下标访问元素时,vector使用vector::size_type作为下标的类型,而数组下标的正确烈性是size_t;
指针可能的取值
一个有效的指针必然是以下三种状态之一:保存一个特定对象的地址;指向某个对象后面的另一个对象;或者是0值。若指针保存0值,表明它不指向任何对象。未初始化的指针是无效的,知道给该指针赋值后。
避免使用未初始化的指针,很多运行时错误都源于使用了未初始化的指针。
如果可能的话,除非所指向的对象已经存在,否者不要先定义指针,这样可避免定义一个未初始化的指针。如果必须分开定义指针和其所指向的对象,则将指针初始化为0.因为编译器可以检测出0值的指针,程序可判断该指针并未指向一个对象。
把int型变量赋给指针是非法的,尽管此int型变量的值可能是0,单允许把数值0 或者在编译时可获得0值的const量赋给指针:
int ival;
int zero = 0;
const int c_ival = 0;
int *pi = ival;//error;
pi = zero;//error
pi = c_ival;//ok
pi = 0;//ok
指针初始化或赋值时必须保证类型匹配。
指向指针的指针:
int ival = 1024;
int *p = &ival;
int **p1 = &p;
int * p2 = *p1;
cout<<*p2<<endl;//1024
cout<<**p1<<endl;//1024
C风格字符串
字符串字面值的类型是字符常量的数组。字符串字面值的类型就是const char类型的数组。实际上,C风格字符串既不能确切地归为C语言类型,也不能归结为C++语言的类型,而是以空字符null结束的字符数组.
C++语言通过(const) char*类型的指针来操纵C风格字符串。一般来说,我们使用指针的算数操作来遍历C风格字符串,每次对指针进行测试并递增1,直到到达结束符null为止:
const char *cp = “some value”;
while(*cp)
{
++cp;
}
如果cp所指向的字符数组没有null结束符,则此循环将会失败。这时候,循环会从cp指向的位置开始读数,知道遇到内存中某处null结束为止。
动态数组:
虽然动态数组的长度是固定的,但是动态分配的数组不必在编译时候知道其长度,可以在运行时才确定数组长度.与数组变量不同,动态分配的数组将一直存在,知道程序显示释放它为止.
动态数组的定义: int *pia =new int[10];
new表达式需要指定指针类型以及在方括号中给出的数组维数,该维数可以是任意的复杂表达式。创建数组后,new将返回指向数组第一个元素的指针。在自由存储区中创建的数组对象是没有名字的,程序员只能通过其地址间接地访问堆中的对象。
如果数组元素是类类型,则使用默认构造函数实现初始化,如果是内置类型,则无初始化:
string *psa = new string[10]//无初始化
可以使用数组长度后面的一对空圆括号,对数组元素做值初始化
int *pia2= new int[10]();
对于动态分配的数组,其元素只能初始化为元素类型的默认值,而不能像数组变量一样,用初始化列表为数组元素提供各不相同的值。
动态空间的释放
C++语言为指针提供delete []表达式释放指针所指向的数组空间:
delete [] pia;
混合使用标准库string和c风格字符串。
string st3(“hello world”);可以欧诺个字符串字面值初始化string类对象。
在要求C风格的字符串的地方不可以直接使用标准库string类型对象。
const char *str = st2.c_str();//ok
因为c_str()返回的指针指向const char类型的上诉组,所以这样做是为了避免修改该数组。