你是如何处理NUL的

How do you deal with NUL?

本文关键字:处理 NUL 何处理      更新时间:2023-10-16

当我们谈论NULL时,我不时会遇到与其他程序员的通信问题。现在NULL可能是

空指针
NUL字符
某种数据库中的空数据元素。


NUL似乎是最令人困惑的。它是ASCII字符0x00。
我倾向于在代码中使用"\0"来表示它。我所在小组的一些开发人员
倾向于简单地使用0,并让编译器隐式地将其转换为char。


你更喜欢用什么来表示NUL?为什么?

我将''用于nul字符,将NULL用于指针,因为它在这两种情况下都是最清晰的。

BTW,0''都是C中的ints,当存储在char变量中时,其中任何一个都将转换为char

我喜欢预定义的NULL宏,因为它保留了语义,而不是数字0的其他用法。

有许多英语单词拼写或口语相似,但含义不同。就像在英语中一样,利用讨论的上下文来引导你达到预期的含义。

  • 对于字符串,我总是将空字符表示为"\0"。
  • 对于指针,我尝试使用隐式转换为布尔值(if(!myPtr)或if(myPtr))来表示指针无效。
  • 如果我需要指针的默认值,它是NULL,例如struct-list_head={0.0,NULL};)。

END_OF_STRING很傻,因为它是一种额外的间接方式,只会让新的读者感到困惑(任何不能立即识别"\0"的人都应该离开键盘)。

还有一件事—我认为在谈论数据建模时,空值和空值之间的区别是非常重要的。在讨论C样式字符串或可为null的数据库字段时尤其如此。有人告诉你"我没有名字"answers"我的名字是"之间有很大的区别

@BKB:

我在他的建议中看到了这一点,但"NULL"使上下文更清楚地表明了它是指针。这就像对浮点值使用"0.0",在处理字符时使用"\0"。(同样,如果在算术上下文中使用char,我更喜欢看到0。)

Bjarne在这个常见问题解答中进一步指出,NULL无论如何都被#定义为0,所以标准代码应该不会有问题。我同意全大写表示法很难看,但我们必须等到0x(nullptr作为关键字可用)。

#define NULL ((void*)0)

这是为了确保NULL被解释为指针类型(在C中)。然而,这可能会在更严格的C++世界中引发问题。例如:

// Example taken from wikibooks.org
std::string * str = NULL; // Can't automatically cast void * to std::string *
void (C::*pmf) () = &C::func;
if (pmf == NULL) {} // Can't automatically cast from void * to pointer to member function.

因此,在当前的C++中,标准的空指针应该用文字0初始化。很明显,因为人们已经习惯了使用NULL定义,我认为很多C++编译器要么默默地忽略这个问题,要么在C++代码中将NULL重新定义为0。例如:

#ifdef __cplusplus
#define NULL (0)
#else
#define NULL ((void*)0)
#endif

C++x0标准现在定义了一个nullptr关键字来表示空指针。Visual C++2005的CLI/C++编译器在将托管指针设置为null时也使用此关键字。在当前的编译器中,您可以创建一个模板来模拟这个新关键字。

wikibooks.org上有一篇更详细的文章讨论这个问题。

A one-L NUL, it ends a string. 
A two-L NULL points to no thing. 
And I will bet a golden bull 
That there is no three-L NULLL. 

(The name of the original author is, alas, lost to the sands of time.)

数据库为NULL,代码为NIL。

虽然总的来说,我建议使用命名常量,但这是一个例外。对我来说,定义:

#define NULL 0
#define END_OF_STRING ''

与定义一样有意义

#define SEVEN 7

没有。是的,我知道编译器已经定义了NULL,但我从不使用它;对于字符,"\0"。更长并不总是意味着更有表现力。

我很喜欢

#define ASCII_NUL ('')

我只是偶尔把"\0"误键入"0"。但当我这样做的时候,我发现代码检查很难发现错误,结果很搞笑。所以我不太喜欢"\0",更喜欢ASCII_NUL或0(当然后者在C++中有错误的类型)。显然,我在需要与现有代码或样式指南保持一致的地方使用"\0"。

谷歌C++风格的指南中包含了一些我喜欢的东西和一些我不喜欢的东西,但似乎大部分都是合理的,它更喜欢NULL而不是0作为指针。它指出,NULL可能不能简单地定义为0(或0L),尤其是在sizeof(void*)可能不是sizeof(int)(或sizeof(long int))的实现中。

0和NULL都被指定为整型,当转换为指针类型时,它们都必须产生一个NULL指针值。但它们不一定是相同的积分类型。因此,在某些情况下,使用NULL可能会得到一些有用的警告或错误。

对于通信,我使用NULL。如果我的开发人员不能理解不同数据类型的NULL概念,那么我会担心。

对于实施,它是针对具体情况的。数字为0(浮点为后置固定f),指针为NULL,字符串为0。

不使用二进制0表示NULL的系统越来越难找到。它们还往往存在各种可移植性问题。为什么?因为在这些系统上,memset和calloc都无法正确清除包含指针的结构。

const char END_OF_STRING = '';

所以当你说:

str[i] = END_OF_STRING;

if (*ptr == END_OF_STRING)

毫无疑问你的意思是什么。

我们使用NULL表示指针,使用NULLCHAR表示字符,使用

#define NULLCHAR ''

有点相关:Slashdot最近在comp.lang.c常见问题部分有一篇关于空指针的报道,我觉得很有趣。