字符串字面值的类型就是 const char 类型的数组,C 风格字符串是以空字符 null 结束的字符数组:
char ca3[] = "C++"; // null terminator added automatically const char *cp = "C++"; // null terminator added automatically
我们使用指针的算术操作来遍历 C 风格字符串,每次对指针进行测试并递增 1,直到到达结束符 null 为止:
const char *cp = "some value"; while (*cp) { // do something to *cp ++cp; }
在使用处理 C 风格字符串的标准库函数时,牢记字符串必须以结束符 null 结束:
char ca[] = {'C', '+', '+'}; // not null-terminated cout << strlen(ca) << endl; // disaster: ca isn't null-terminated在这个例题中, ca 是一个没有 null 结束符的字符数组,则计算的结果不可预料。标准库函数 strlen 总是假定其参数字符串以 null 字符结束
数组类型的变量有三个重要的限制:数组长度固定不变,在编译时必须知道其长度,数组只在定义它的块语句内存在。实际的程序往往不能忍受这样的限制——它们需要在运行时动态地分配数组。虽然数组长度是固定的,但动态分配的数组不必在编译时知道其长度,可以(通常也是)在运行时才确定数组长度。与数组变量不同,动态分配的数组将一直存在,直到程序显式释放它为止。
动态分配数组时,如果数组元素具有类类型,将使用该类的默认构造函数(第 2.3.4 节)实现初始化;如果数组元素是内置类型,则无初始化:
string *psa = new string[10]; // array of 10 empty strings int *pia = new int[10]; // array of 10 uninitialized ints
也可使用跟在数组长度后面的一对空圆括号,对数组元素做值初始化(第 3.3.1 节):
int *pia2 = new int[10] (); // array of 10 uninitialized ints
数组元素都设置为0。
之所以要动态分配数组,往往是由于编译时并不知道数组的长度。我们可以编写如下代码
size_t n = get_size(); // get_size returns number of elements needed int* p = new int[n]; for (int* q = p; q != p + n; ++q)在释放动态数组时千万别忘了方括号对。delete [] pia;
无法使用 string 对象初始化字符指针:
char *str = st2; // compile-time type error
string 类提供了一个名为 c_str 的成员函数,以实现我们的要求:
char *str = st2.c_str(); // almost ok, but not quite
c_str 函数返回 C 风格字符串,其字面意思是:“返回 C 风格字符串的表示方法”,即返回指向字符数组首地址的指针,该数组存放了与 string 对象相同的内容,并且以结束符 null 结束。
如果 c_str 返回的指针指向 const char 类型的数组,则上述初始化失败,这样做是为了避免修改该数组。正确的初始化应为:
const char *str = st2.c_str(); // ok