我是否可以使用NULL
指针代替0
的值?
或者这样做有什么问题吗?
例如,例如:
int i = NULL;
作为替代:
int i = 0;
作为实验,我编译了以下代码:
#include <stdio.h>
int main(void)
{
int i = NULL;
printf("%d",i);
return 0;
}
输出:
0
事实上,它给了我这个警告,它完全是正确的:
warning: initialization makes integer from pointer without a cast [-Wint-conversion]
但是结果仍然相等。
NULL
一起使用?NULL
作为数值有什么错误吗?我已经阅读了What is the difference between NULL, '\0' and 0的答案,关于NULL
,\0
和0
之间的区别是什么,但是我没有从那里得到简洁的信息,如果它是完全可以允许的并且也是正确使用的话NULL
作为要在赋值和其他算术运算中使用的值。
NULL
与零互换使用。例如,在此代码示例中char const* foo = "bar";
foo + 0;
不能用0
替换NULL
是有效的C程序,因为未定义两个指针之间的加法(更不用说不同的指针类型了)。由于违反约束,将导致发出诊断信息。 The operands for addition will not be valid。
对于C ++,情况有所不同。缺少从
void*
到其他对象类型的隐式转换意味着NULL
在C ++代码中历来被定义为0
。在C ++ 03中,您可能会摆脱它。但是从C ++ 11开始,它可以合法地be defined as thenullptr
keyword。由于nullptr
可能未添加到指针类型,因此现在再次产生错误。
如果std::nullptr_t
被定义为NULL
,那么即使您的实验也变得无效。nullptr
没有转换为整数。这就是为什么它被认为是更安全的空指针常量。
No,这样做是不安全的。
std::nullptr_t
是一个空指针常量,其可能具有类型
NULL
,但更通常具有类型int
。该语言允许将指针转换为整数,但是它不提供在不进行强制转换的情况下执行此类转换的功能(尽管某些编译器将其作为扩展提供)。此外,尽管将空指针转换为整数以产生值0是很常见的,但标准并不能保证这样做。如果要使用类型void *
和值0的常量,则将其拼写为int
。我可能会由此陷入不确定的行为吗?是,在任何将
0
扩展为类型为NULL
的值的实现上。该标准未定义您在此类实现上的行为,因此,其行为未定义。 是否可以通过这种方式使用NULL?
void *
选项进行编译,它将在您自己的示例中中断。在算术表达式中使用NULL作为数值是否有问题?
在那种情况下,C ++的结果如何?
-Werror
具有不同的规则,但是实现也可以提供扩展。同样,如果您的意思是0,那您应该写。NULL
规则在语言及其版本之间有所不同。在某些情况下,您
可以,而在某些情况下则不能。无论如何,您不应。如果幸运的话,当您尝试编译时,甚至在更好的情况下,编译器将发出警告,但编译失败。
在C ++中,在C ++ 11之前(引自C ++ 03):[lib.support.types]
NULL是此国际标准中的实现定义的C ++空指针常量。将空指针常量用作整数几乎没有意义。但是...
[conv.ptr]
空指针常量是整数类型的整数常量表达式(5.19)rvalue,其值为零。因此,即使它毫无意义,它在技术上也能正常工作。由于这种技术,您可能会遇到编写不良的程序,这些程序滥用
int i = NULL;
。自C ++ 11起(引自最新草案):
[conv.ptr]
空指针常量是值为零的整数文字([lex.icon])。或类型为std :: nullptr_t的prvalue
A
P.S。NULL
不能转换为整数,因此根据语言实现的选择,将std::nullptr_t
用作整数只能有条件地工作。NULL
是类型nullptr
的prvalue。除非需要在C ++ 11之前的版本中编译程序,否则应始终使用std::nullptr_t
而不是nullptr
。C有点不同(引自C11 N1548草案):
6.3.2.3语言/转换/其他操作数/指针
3值为0的整数常量表达式,,称为空指针常量。 ...或此类类型转换为类型
NULL
因此,这种情况类似于C ++ 11之后的情况,即
void *
的使用取决于语言实现所做出的选择,有条件地起作用。
[NULL
是值为零的'\0'
,与int
完全一样,只是100%。
0
在指针的上下文中,都是100%等效的。for (int k = 10; k > '\0'; k--) /* void */; for (int k = 10; k > 0; k--) /* void */;
和0
等于100%:
NULL
。没有定义使用C语言添加指针。可以将指针和整数相加(或相减)。在关于
if (ptr) /* ... */; if (ptr != NULL) /* ... */; if (ptr != '\0') /* ... */; if (ptr != 0) /* ... */;
的注意事项ptr + NULL
的上下文是指针的not
ptr + NULL
中,如果ptr + NULL
或ptr
是指针,则另一个必须为整数,因此NULL
实际上是ptr + NULL
或(int)ptr + NULL
,并取决于ptr + (int)NULL
的定义和ptr
可以预期以下几种行为:全部正常运行,警告指针和整数之间的转换,编译失败,...
Q:如果NULL和0等价于null指针常量,我应该使用哪个?A:仅在指针上下文中,
NULL
和NULL
是等效的。当需要另一种0时,应该使用0
not,即使它可能起作用,因为这样做会发送错误的样式信息。 (此外,ANSI允许NULL的定义为
NULL
,在非指针上下文中根本不起作用。)特别是,当需要ASCII空字符(NUL)时,请勿使用((void *)0)
。提供您自己的定义NULL
may取决于实现,但需要强制转换。但是,是的,否则它是100%合法的。
尽管它确实是非常非常糟糕的风格(不用说?)。>http://c-faq.com/null/nullor0.html是或曾经是实际上
不是C ++,它是C。但是,标准does
与许多C传统一样,有两个子句([diff.null]和[support。类型[nullptr]),从技术上讲是NULL
C ++。它是实现定义的空指针常量。因此,即使样式不好,它在技术上也尽可能地像C ++。正如NULL
中指出的,可能的实现方式可以是footnote或0
,但not 0L
。(void*)0
当然可以(标准没有明确说明,但它几乎是NULL
或0
之后剩下的唯一选择)是0L
。几乎从来没有这样,但这是合法的可能性。编译器向您显示的警告表明该编译器实际上不兼容(除非您以C模式进行编译)。因为,根据警告,它did convert
空指针(不是nullptr
,该指针将是nullptr
,这将是截然不同的),因此,nullptr_t
的定义显然是[C0 ],可能不是。无论哪种方式,您都有两种可能的合法(即编译器未损坏)情况。无论哪种情况(现实情况),NULL
都类似于(void*)0
或NULL
,那么您可以将“零或一”
或者0
的确是0L
。在这种情况下,您拥有一个独特的值,该值可以保证比较以及明确定义的转换from
to
整数。但是,它确实具有对NULL
的明确定义的转换(导致nullptr
),并且bool
具有对角的明确定义的转换(导致false
)。很不幸,这是two转换,因此它不在[[conv]中指出的“零或一”]之内。因此,如果您的实现将bool
定义为0
,那么您将必须添加显式强制类型转换才能使代码正确。