字符串常量包含一个字符序列(也包括空格),均位于一个双引号中,例如:
“Hello world!/n”
与字符常量一样,字符串常量可以包含源字符集中的所有字符,唯一例外就是使用双引号,反斜杠(/)、换行符等需要通过转义来表示,下面printf语句中首先产生一个警告音,接着,在双引号中指定一个目录,使用%s来替代指针doc_path的地址:
Char doc_path[128] = “.//share//doc”;
Printf(“/aSee the documentation in the directory /”%s/”/n”, doc_path”);
字符串常量是一个静态char数组,它包含以字符串结束符null(/0)结束的字符码。空串””在内存中占用一个字节,因为它包含了null字符。不能用一字节存储的字符使用多字节来存储。
如前面所有的例子,你可以使用一个字符串来初始化一个字符数组,也可以用它来初始化一个char指针:
Char *pStr = “Hello, world!”; //pStr points to the first character, ‘H’
在这种初始化中,字符串常量表示每一个元素的地址,这跟数组名是一样的。
在Example 3-1中,数据error_msg包含3个char指针,每一个赋值一个字符串首字母的地址。
Example 3-1. Sample function error_exit( )
#include <stdio.h>
#include <stdlib.h>
Void error_exit(unsigned int error_n)
{
Char *error_msg[] = {“Unknown error code./n”,
“Insufficient memory./n”,
“Illegal memory access./n”};
Unsigned int arr_len = sizeof(error_msg)/sizeof(char *);
If (error_n > = arr_len)
Error_n = 0;
Fput(error_msg[error_n], stderr);
Exit(1);
}
与宽字符常量一样,你可以使用前缀L在字符串常量中使用宽字符:
L”Here`s a wide-string literal.”
宽字符串常量定义一个以null结束的数组,它的元素类型为wchar_t,数组通过转换多字节为宽字符来初始化,这与标准函数mbstowcs()一样。同样地,使用转义表示的任何通用字符名以单个的宽字符存储。
在下面的例子中, /u03b1表示通用字符a,wprintf()为printf函数的宽字符版本。用来格式化和打印一个宽字符串:
Doubel angle_alpha = 90.0/3;
Wprintf(L”Angel /u03b1 measures %lf degress./n”, angle_alpha);
字符串常量中的任何多字节字符或转义字符均不能在执行时字符集中表示,它们的值取决于编译器。
编译预处理器连接任何以空格隔开的单个相邻字符,如下所示,这种连接使为了字符串易于阅读而分成多行变得容易了:
#define PRG_NAME “EasyLine”
Char msg[] = “The installation of ” PRG_NAME
“is now complete.”;
如果连接的任一字符串是宽字符常量,刚连接后的结果串也为一个宽字符串。
另一种分隔一个字符串为多行的方法是使用反斜杠结束,如下面的例子:
Char info[] =
“This is a string literal broken up into /
Several source code lines./nNow one more line:/n/
That`s enough, the string ends here.”;
字符串将在新行的开始继续,任何在左页边的空格,例如several前的空格,均是字符串的一部分,此外,此串包含了两个换行符,一个在Now前,另一个在that`s之前。
编译器解释转义字符在连接相邻串之前,所以,下面来自一个宽字符串的两个字符串常量以’/xA7’和’2’开始:
L”/xA7” L”2 et cetera”
然而,如果这个串写在一起,如L”/xA72 et cetera”,则串中每个字符为宽字符’/xA72’。
虽然C没有严格禁止修改字符串常量,你也不应该尝试这样做,在下例中,第二个语句就是尝试替换字符串是首字符:
Char *p = “house”; //Initialize a pointer to char
*p = ‘m’; //This is not a good idea!
这个语句不被禁止,但在有些系统上会引起运行时错误,首先,编译器当做一个常量去处理字符串,可能将它置于只读内存,所以试图进行写操作将会引起错误,其次,如果两个或更多的相同串在程序中使用,编译器会将它们存储在相同的位置,所以修改可能会引起另外一个使用它的地方出现异常。
然而,当你使用一个字符串来初始化数组变量,你可以修改数组内容:
Char s[] = “house” //Initialize an array of char
S[0] = ‘m’ //Now the array contains the string “mouse”.