你如何处理NUL?

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

一个NULL指针
NUL角色
某种数据库中的空数据元素。

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

您更喜欢NUL使用什么? 为什么?

我使用'\0'作为nul-character,使用NULL作为指针,因为它在两种情况下都是最清晰的。

顺便说一句, 0'\0'都是C中的int ,当存储在char变量中时,任何一个都将转换为char

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

有许多英语单词拼写或说话相似,但具有不同的含义。 与英语一样,使用进行讨论的上下文来指导您达到预期的含义。

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

END_OF_STRING是愚蠢的,因为它是额外的间接,简单地混淆了新读者(任何不能立即识别’\ 0’的人都应该离开键盘)。

另一件事 – 我认为在谈论数据建模时,空值和空值之间的区别非常重要。 在讨论C风格的字符串或可空数据库字段时尤其如此。 有人告诉你“我没有名字”和“我的名字是”,这有很大的不同。

如果我没记错的话,大多数C编译器都会像这样定义NULL:

 #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关键字来表示空指针。 在将托管指针设置为null时,Visual C ++ 2005的CLI / C ++编译器也使用此关键字。 在当前的编译器中,您可以创建模板来模拟这个新关键字。

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

@BKB:

我在他的建议中看到了这一点,但“NULL”使得上下文更加清晰。 这就像在浮点值中使用“0.0”,在处理字符时使用’\ 0’。 (同样,如果在算术上下文中使用char,我更喜欢看到0。)

Bjarne在本FAQ中进一步指出NULL无论如何都是#defined为0,因此标准代码应该没有问题。 我同意全大写符号是丑陋的,但我们必须等到0x(其中nullptr可用,作为关键字。)

 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 '\0' 

与定义一样有意义:

 #define SEVEN 7 

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

我相当喜欢

 #define ASCII_NUL ('\0') 

我偶尔会错误地将’\ 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概念的开发人员合作,那么我会担心。

为了实现它是特定于案例的。 数字为0(浮点后固定f),指针为NULL,字符串为0。

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

 const char END_OF_STRING = '\0'; 

所以当你说:

 str[i] = END_OF_STRING; 

要么

 if (*ptr == END_OF_STRING) 

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

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

 #define NULLCHAR '\0' 

相关的排序:Slashdot最近在关于空指针的comp.lang.c FAQ部分有一个故事,我发现它非常有趣。