对C的char *字符串使用NULL

时间:2018-09-21 21:31:53

标签: c++ c null c-strings

众所周知,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)。对于此代码的合法性,我仍然感到非常好奇-而且这里的声音似乎参差不齐-在我看来,重复的代码并未对此给出权威性的答案。

3 个答案:

答案 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空字符的正式名称匹配。