为什么空指针在C和C ++不同的定义? [英] Why are NULL pointers defined differently in C and C++?

查看:101
本文介绍了为什么空指针在C和C ++不同的定义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C, NULL 定义为(无效*)0 ,而在C ++中是 0 。为什么会这样呢?
在C我能理解,如果 NULL 不强制转换为(无效*)然后编译器可能/可能不会产生警告。除此之外,还有什么原因?

In C, NULL is defined as (void *)0 whereas in C++ it is 0. Why is it so? In C I can understand that if NULL is not typecast to (void *) then compilers may/may not generate warning. Other than this, is there any reason?

推荐答案

在C ++中,空指针是由ISO规范(宗; 4.10 / 1)定义为

In C++, the null pointer is defined by the ISO specification (§4.10/1) as

一个空指针常量是一个整型常量前pression(5.19)计算结果为零整数类型的右值。

A null pointer constant is an integral constant expression (5.19) rvalue of integer type that evaluates to zero.

这就是为什么在C ++中,你可以写

This is why in C++ you can write

int* ptr = 0;

在C,这个规则是相似的,但有点不同(宗; 6.3.2.3/3):

In C, this rule is similar, but is a bit different (§6.3.2.3/3):

值为0,或者这样的前pression投整型常量前pression键入
  无效* ,被称为一个空指针constant.55)如果空指针常量将被转换为
  指针类型,所得到的指针,称为空指针,​​被保证比较不等
  的指针的任何对象或功能。

An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.55) If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.

因此​​,无论

int* ptr = 0;

int* ptr = (void *)0

是合法的。不过,我的猜测是,无效* 投在这里,使之类的语句

are legal. However, my guess is that the void* cast is here so that statements like

int x = NULL;

产生在大多数系统上编译器警告。在C ++中,这不会是合法的,因为你不能隐式转换无效* 隐另一个指针类型不进行强制转换。例如,这是非法的:

produce a compiler warning on most systems. In C++, this wouldn't be legal because you can't implicitly convert a void* to another pointer type implicitly without a cast. For example, this is illegal:

int* ptr = (void*)0; // Legal C, illegal C++

然而,这将导致问题,因为code

However, this leads to issues because the code

int x = NULL;

是合法的C ++。因为这和随之而来的混乱(和另一种情况,后来所示),C ++ 11现在有一个关键字的 nullptr 重新presenting一个空指针:

is legal C++. Because of this and the ensuing confusion (and another case, shown later), C++11 now has a keyword nullptr representing a null pointer:

int* ptr = nullptr;

此没有任何的上述问题。

This doesn't have any of the above problems.

nullptr 超过0的另一个优点是,它起着与C ++类型系统更好。例如,假设我有这两个功能:

The other advantage of nullptr over 0 is that it plays better with the C++ type system. For example, suppose I have these two functions:

void DoSomething(int x);
void DoSomething(char* x);

如果我称之为

DoSomething(NULL);

这是等同于

DoSomething(0);

它调用 DoSomething的(INT)而不是预期的 DoSomething的(字符*)。然而,随着 nullptr ,我可以写

which calls DoSomething(int) instead of the expected DoSomething(char*). However, with nullptr, I could write

DoSomething(nullptr);

和它将调用 DoSomething的(字符*)功能如预期。

And it will call the DoSomething(char*) function as expected.

同样的,假设我有一个矢量<对象* GT; 并要设置的每个元素是一个空指针。使用的std ::填写算法,我可能会尝试写

Similarly, suppose that I have a vector<Object*> and want to set each element to be a null pointer. Using the std::fill algorithm, I might try writing

std::fill(v.begin(), v.end(), NULL);

不过,这并不能编译,因为模板系统治疗 NULL INT ,而不是一个指针。为了解决这个问题,我会写

However, this doesn't compile, because the template system treats NULL as an int and not a pointer. To fix this, I would have to write

std::fill(v.begin(), v.end(), (Object*)NULL);

这是丑陋的,有点违背了模板系统的目的。为了解决这个问题,我可以使用 nullptr

This is ugly and somewhat defeats the purpose of the template system. To fix this, I can use nullptr:

std::fill(v.begin(), v.end(), nullptr);

和自 nullptr 是已知有对应于空指针(具体而言,的std :: nullptr_t A型),这将正确编译。

And since nullptr is known to have a type corresponding to a null pointer (specifically, std::nullptr_t), this will compile correctly.

希望这有助于!

这篇关于为什么空指针在C和C ++不同的定义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆