C语言字符串数组详解
C语言字符串数组
字符串是连续的字符序列,最后以空字符'\0'作为终止符。一个字符串的长度指所有字符的数量,但不包括终止符。在 C 语言中,没有字符串类型,自然也就没有运算符以字符串为操作数。
字符串被存储在元素类型为 char 或宽字符类型数组中(宽字符类型指 wchar_t、char16_t 或 char32_t)。宽字符组成的字符串也称为宽字符串(wide string)。
C 标准库提供了大量的函数,它们可以对字符串进行基本操作,例如字符串的比较、复制和连接等。在这些传统的字符串函数以外,C11 新增了这些函数的“安全”版本,它们能确保字符串操作不会超出数组的边界。
可以使用字符串字面量来初始化任何字符类型数组。例如,下面两个数组的定义是等价的:
char str1[30] = "Let's go"; // 字符串长度:8;数组长度:30 char str1[30] = { 'L', 'e', 't', '\'', 's',' ', 'g', 'o', '\0' };
存储字符串的数组一定比字符串长度多一个元素,以容纳下字符串终止符(空字符'\0')。因此,str1 数组能够存储的字符串最大长度是 29。如果定义数组长度为 8,而不是 30,就会发生错误,因为它无法包含字符串终止符。
如果在定义一个字符数组时,没有显式地指定长度,但使用了字符串字面量来对它进行初始化,该数组的长度会比字符串长度多 1。如下列所示:
char str2[] = " to London!"; // 字符串长度:11 (注意开头的空格); // 数组长度:12
下面的语句使用标准函数 strcat()把字符串 str2 附加到字符串 str1 的后面(str1 数组长度必须足够大以容纳连接后的全部字符)。
#include <string.h> char str1[30] = "Let's go"; char str2[ ] = " to London!"; /* ... */ strcat( str1, str2 ); puts( str1 );
调用 puts()后,输出新的 str1 数组内容:
Let's go to London!
str1 和 str2 的名字其实是两个指针,它们指向各自数组的第一个字符。这样的指针被称为指向字符串的指针(pointer to a string),或者简称为字符串指针(string pointer)。
字符串处理函数(例如 scrcat()和 puts())需要接收字符串起始地址并将其作为参数。这样的函数通常逐个字符地处理字符串,直到遇到结尾终止符'\0'为止。
例 1 是函数 strcat()的另――种可能的实现方式。它采用从函数参数传入的指针遍历处理整个字符串。 【例1】函数 strcat()
// 函数strcat() 将第二个字符串复制一份并附加到第一个字符串的尾部 // 参数:指向两个字符串的指针 // 返回值:指向第一个字符串的指针,此时已将第二个字符串连接到了其尾部 char *strcat( char * restrict s1, const char * restrict s2 ) { char *rtnPtr = s1; while ( *s1 != '\0' ) // 找到字符串s1的尾部 ++s1; while (( *s1++ = *s2++ ) != '\0' ) // 将s2的首字符替换掉s1的终止符 ; return rtnPtr; }
以 s1 地址为起始位置的 char 数组,其长度至少是两个字符串长度的和再加上 1,以容纳字符串终止符。在调用 strcat()之前,可以采用标准函数 strlen()进行测试,以确保长度没有问题,函数 strlen()返回其字符串参数的长度,如下所示:
if ( sizeof(str1) >= ( strlen( str1 ) + strlen( str2 ) + 1 ) ) strcat( str1, str2 );
宽字符串字面量会加上一个前缀 L、u 或 U,它们是宽字符串的标志。因此,wchar_t 数组的初始化过程如下所示:
#include <stddef.h> // 定义wchart_t类型 /* ... */ wchar_t dinner[] = L"chop suey"; // 字符串长度:10; // 数组长度:11; // 数组空间大小:11 * sizeof(wchar_t)