C常量字符串是否始终为空终止?

时间:2017-11-14 14:59:12

标签: c string

C常量字符串是否始终以空例句终止而无异常?

例如,以下C代码是否始终打印为“true”:

const char* s = "abc";
if( *(s + 3) == 0 ){
   printf( "true" );
} else {
   printf( "false" );
} 

4 个答案:

答案 0 :(得分:11)

如果字符串包含空字符,则该字符串只是字符串

  

string 是由第一个空字符终止并包含第一个空字符的连续字符序列。 C11§7.1.11

"abc"是一个字符串文字。它也总是包含一个空字符。 字符串文字可能包含多于1个空字符。

"def\0ghi"  // 2 null characters.

但是,在下文中,x不是字符串(它是char的数组,没有空字符)。 yz都是char的数组,都是字符串。

char x[3] = "abc";
char y[4] = "abc";
char z[] = "abc";

使用OP的代码,s指向字符串,字符串文字"abc"*(s + 3)s[3]的值为0。尝试修改s[3]是未定义的行为1)sconst char *和2)s指向的数据是字符串文字。尝试修改字符串文字也是未定义的行为。

const char* s = "abc";

更深:C没有定义“常量字符串”。

该语言定义字符串文字,如"abc"为大小为4的字符数组,其值为'a''b',{{1 },'c'。试图修改这些是UB。如何使用取决于具体情况。

标准C库定义 string

使用'\0'const char* s = "abc";指针,用于s类型的数据。作为char指针,使用const some_type *修改数据是UB。 s 已初始化以指向字符串文字 s"abc"本身不是字符串。内存s的初始点是字符串

答案 1 :(得分:6)

简而言之,是的。 字符串常量当然是字符串,字符串按定义为0终止。

如果您使用字符串常量作为数组初始值设定项,请执行以下操作:

char x[5] = "hello";

你在x中没有{0}终结者只是因为没有空间。

但是

char x[] = "hello";

它会在那里,x的大小为6。

答案 2 :(得分:2)

字符串的概念被确定为由零字符终止的字符序列。序列是否可修改并不重要,即相应的声明是否具有限定符const

例如,C中的字符串文字具有非常量字符数组的类型。所以你可以写一些例如

char *s = "Hello world";

在此声明中,标识符s指向字符串的第一个字符。

您可以使用字符串文字通过字符串自己初始化字符数组。例如

char s[] = "Hello world";

此声明相当于

char s[] = { 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '\0' };

但是在C中,您可以从字符数组的初始化中排除终止零。

例如

char s[11] = "Hello world"; 

虽然用作初始化程序的字符串文字包含终止零,但它从初始化中排除。结果,字符数组s不包含字符串。

答案 3 :(得分:1)

在C中,没有像C ++和Java那样的“字符串”数据类型。

每个主管计算机科学学位课程都应该提到的重要原则:信息是符号加解释

“字符串”通常定义为以空字节('\ 0')结尾的任何字符序列。

正在发布的“陷阱”(字符/字节数组中间值为0)只是解释的差异。将字节数组作为字符串处理而不是将其视为字节([0,255]中的数字)具有不同的应用程序。显然,如果您要打印到终端,您可能需要打印字符,直到达到空字节。如果要保存文件或在数据块上运行加密算法,则需要在字节数组中支持0。

获取“字符串”并选择将其解释为字节数组也是有效的。