众所周知,C中的字符串是空终止的。这是否意味着根据标准,使用NULL常量作为终止符是合法的?还是一个字符串的NULL指针和null终止符的名称的相似只是一个快乐的巧合?
考虑代码:
char str1[] = "abc";
char str2[] = "abc";
str1[3] = NULL;
str2[3] = '\0';
在这里,我们将str1
的终止符更改为NULL。这是合法且格式正确的C代码,并且str1
遵循C对以null结尾的字符串的定义吗?如果使用C ++,会一样吗?
实际上,我一直在代码中使用NULL而不是'\ 0'来处理字符串,并且一切正常-但是这种做法100%合法吗?
编辑:我知道这是非常糟糕的样式,请不要认可它,现在可以理解0,NULL和'\ 0'之间的区别(如重复的What is the difference between NULL, '\0' and 0)。对于此代码的合法性,我仍然感到非常好奇-而且这里的声音似乎参差不齐-在我看来,重复的代码并未对此给出权威性的答案。
答案 0 :(得分:3)
这是否意味着根据标准,使用NULL常量作为终止符是合法的? (OP)
str1[3] = NULL;
Sometimes。更进一步:它是否总是正确地使 character 数组形成 string 而不引起关注?
首先,它看起来不对。类似于int z = 0.0;
。是的,它是法律明确定义的代码,但不必要地引起人们的注意。
实际上,我一直使用
NULL
代替'\0'
(OP)
我怀疑您会发现任何现代风格的指南或支持这一观点的编码人员。 NULL
最好保留给指针上下文。 1
这些是2种常见且众所周知的替代方案。
str1[3] = '\0';
str1[3] = 0;
C中的字符串以空值结尾(OP)
C规范始终使用 null字符,而不仅仅是使用 null 。
宏是
NULL
,它扩展为实现定义的空指针常量;和... C11§7.193
好的,什么是空指针常量?
值为0的整数常量表达式,或将其强制转换为类型的表达式
void *
被称为空指针常量。 §6.3.2.35
如果空指针常量是void*
,那么我们会得到类似的
str1[3] = (void*) 0;
以上内容可以警告将指针转换为char
。最好避免这种情况。
在C ++中会一样吗? (OP)
是的,以上适用。 (此外:str1[3] = 0
可能会发出警告。)此外,与nullptr
相比,NULL
的优先级较低。因此,NULL
在任何情况下都很少是在C ++中最好的使用。
1 注意:@Joshua报告的样式与1995年Turbo C 4.5中的OP相匹配
答案 1 :(得分:3)
最重要的是,在C / C ++中,NULL
用于指针,并且与空字符不同,尽管事实上被定义为零。您可以将NULL
用作空字符,并根据上下文和平台来使用它,但请正确使用'\0'
。在两个标准中都对此进行了描述:
C指定将宏NULL
定义为<stddef.h>
中的宏,该宏“扩展为实现定义的空指针常量”(第7.17.3节),该宏本身已定义表示为“值为0的整数常量表达式,或此类类型转换为类型void *
”(第6.3.2.3.3节)。
空字符在第5.2.1.2节中定义:“基本执行字符集中应存在一个所有位都设置为0的字节,称为空字符”;一个字符串。”同一部分说明\0
将代表此空字符。
C ++具有相同的区别。根据C ++标准的4.10.1节:“空指针常量是整数文字(2.13.2),其值为零或类型为std::nullptr_t
的prvalue。”在2.3.3节中,它描述为“ null字符(分别为null宽字符),其值为0”。 C.5.2节进一步确认,C ++将NULL
视为从C标准库导入的标准宏。
答案 2 :(得分:1)
不,我认为这绝对不合法。
NULL
被指定为:
0
的整数常量表达式0
转换为类型void*
在使用第一种格式的实现中,可以将其用作字符串终止符。
但是在使用第二种格式的实现中,不能保证它能正常工作。您将指针类型转换为整数类型,其结果与实现有关。它恰好可以在常见的实现中完成您想要的事情,但是并不需要它。
如果您使用第二种类型的实现,则可能会收到如下警告:
警告:指向整数转换的不兼容指针,从“ void *” [-Wint-conversion]分配给“ char”
如果要使用宏,则可以定义:
#define NUL '\0'
,然后使用NUL
代替NULL
。这与ASCII空字符的正式名称匹配。