有时候,我与其他程序员交流时,会遇到关于NULL的沟通问题。现在NULL可能是:
一个NULL指针
NUL字符
某种数据库中的空数据元素。
NUL似乎最令人困惑。它是ASCII字符0x00。
我倾向于在我的代码中使用'\0'来表示它。我的一些同事倾向于只使用0,并让编译器隐式地将其转换为char。
你更喜欢使用哪个来代表NUL?为什么?
有时候,我与其他程序员交流时,会遇到关于NULL的沟通问题。现在NULL可能是:
一个NULL指针
NUL字符
某种数据库中的空数据元素。
NUL似乎最令人困惑。它是ASCII字符0x00。
我倾向于在我的代码中使用'\0'来表示它。我的一些同事倾向于只使用0,并让编译器隐式地将其转换为char。
你更喜欢使用哪个来代表NUL?为什么?
我在表示空字符时使用'\0'
,在指针方面则使用NULL
,因为在两种情况下都很清晰。
顺便提一下,在C语言中,0
和'\0'
都是int
类型的,当存储在char
变量中时会被转换为char
。
int
类型。它是一个特殊的整数字面量,没有具体的类型,但可以在int
或指针上下文中使用(就像C#中的null
一样)。 - Pavel Minaev我喜欢预定义的NULL宏,因为它保留了语义意义,而不是使用数字0的其他用法。
有许多英文单词的拼写或发音相同,但意义不同。与英语类似,使用讨论所在的上下文来指导您找到预期的含义。
END_OF_STRING很傻,因为这只会使新读者感到困惑(任何不立即认识'\0'的人都应该离开键盘)。
还有一件事——我认为在讨论数据建模时,null值和空值之间的区别非常重要。特别是在讨论C风格的字符串或可空数据库字段时。当有人告诉你“我没有名字”和“我的名字是 ”之间有很大的差异。
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.)
如果我记得正确,大多数C编译器将NULL定义为以下内容:
#define NULL ((void*)0)
// 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.
#ifdef __cplusplus
#define NULL (0)
#else
#define NULL ((void*)0)
#endif
nullptr
关键字来表示空指针。Visual C++ 2005的CLI/C++编译器在将托管指针设置为null时也使用此关键字。在当前的编译器中,您可以创建一个模板来模拟这个新关键字。@BKB:
我理解他的建议,但是使用"NULL"可以更清晰地表明上下文是指针。就像在处理字符时使用'\0',浮点数值时使用"0.0"一样。(同样地,如果char在算术上下文中使用,我更喜欢看到0。)
Bjarne在这篇FAQ中进一步说明了NULL已经被定义为0,因此标准代码不应该有问题。我同意全大写符号的表示法很丑陋,但我们必须等到0x (nullptr将作为关键字可用)。
我相当喜欢
#define ASCII_NUL ('\0')
我很少将 '\0' 打错成 '0'。但是当我犯了这个错误时,通过代码检查很难发现错误,结果非常滑稽。所以我不太喜欢 '\0',更喜欢 ASCII_NUL 或 0(当然后者在 C++ 中类型错误)。显然,我会在需要与现有代码或样式指南保持一致的情况下使用 '\0'。
Google C++ 样式指南包含一些我喜欢和一些我不喜欢的东西,但似乎大多数都很合理,它更喜欢用 NULL 代替 0 来表示指针。它指出,在某些实现中,NULL 可能不仅仅被定义为 0(或 0L),特别是在 sizeof(void*) 可能不等于 sizeof(int)(或 sizeof(long int))的情况下。
0 和 NULL 都被指定为整数类型,并且当转换为指针类型时,它们都必须产生空指针值。但它们不一定是相同的整数类型。因此,在某些情况下,使用 NULL 可能会得到一些有用的警告或错误提示。
虽然总体上我建议使用命名常量,但这里有一个例外。对我来说,定义:
#define NULL 0
#define END_OF_STRING '\0'
这句话的意思就像定义:
#define SEVEN 7
没有。是的,我知道编译器已经定义了NULL,但我从不使用它。对于指针,用0;对于字符,用'\0'。更长并不总是意味着更具表现力。
数据库用NULL,代码用NIL。