C++ 用指针书写条件的几种方法的差异

C++ 用指针书写条件的几种方法的差异,c++,C++,我想知道是否有人可以总结一下编写包含指针的条件语句的以下几种方法之间的差异: if(p) if(p != 0) if(p != NULL) if( p != nullptr ) 我经常对以下情况感到困惑(必须有更多,请补充您的情况)何时使用: static char *p1; char *p2 = new char(); const char *p3 = "hello"; /*then I repeatedly do p3++*/ char *p4 = 0; char *p5 = NULL;

我想知道是否有人可以总结一下编写包含指针的条件语句的以下几种方法之间的差异:

if(p)
if(p != 0)
if(p != NULL)
if( p != nullptr )
我经常对以下情况感到困惑(必须有更多,请补充您的情况)何时使用:

static char *p1;
char *p2 = new char();
const char *p3 = "hello"; /*then I repeatedly do p3++*/
char *p4 = 0;
char *p5 = NULL;
编辑

另外,我想知道,对于
char*p
,在while循环中的一些
p++
之后,我们是否有
while(*p!=0)或
while(*p!=0)
,可能相当于
while(p)
while(p!=NULL)
while(*p!='\0')
(或任何其他?)

if(p)
在此上下文中,
p
被转换为
bool
,这实际上与
p!=0

if(p!=0)
这是检查空指针的显式方法,与前一种方法相同

if(p != NULL)
与此不同的是,
NULL
是一个宏;在C中定义为<代码>(空洞*)0 < /代码>,而C++中定义为<代码> 0 < /C>。同样,它与前两个表达式的检查相同

基本上,它们都做相同的事情(除了
NULL
宏没有定义或被重新定义为其他内容)。我倾向于使用
p!=0
,因为它与
p
相同,但它的声明是明确的。使用
NULL
的版本需要包含
stddef
cstddef
,这通常不是问题

在C++11中,有一种检查空指针的新方法:
nullptr
,这是一个新的关键字。如果可用,它将是理想的选择,因为它清楚地表明
p
是一个指针:

if(p)
if(p != 0)
if(p != NULL)
if( p != nullptr )
在此上下文中,
p
被转换为
bool
,这实际上与
p!=0

if(p!=0)
这是检查空指针的显式方法,与前一种方法相同

if(p != NULL)
与此不同的是,
NULL
是一个宏;在C中定义为<代码>(空洞*)0 < /代码>,而C++中定义为<代码> 0 < /C>。同样,它与前两个表达式的检查相同

基本上,它们都做相同的事情(除了
NULL
宏没有定义或被重新定义为其他内容)。我倾向于使用
p!=0
,因为它与
p
相同,但它的声明是明确的。使用
NULL
的版本需要包含
stddef
cstddef
,这通常不是问题

在C++11中,有一种检查空指针的新方法:
nullptr
,这是一个新的关键字。如果可用,它将是理想的选择,因为它清楚地表明
p
是一个指针:

if(p)
if(p != 0)
if(p != NULL)
if( p != nullptr )

这些都是检查
p
是否为
0
的方法;他们做同样的事情:

if(p)            // Short and simple.
if(p != 0)       // Easier to understand.
if(p != NULL)    // POINTERS ONLY.
在C++11中,您可以使用这种“更安全”的方式:


当您想要创建一个
char
s的“动态分配”数组时,您可以执行以下操作:

char *p2 = new char[4];
strcpy(p2, "abc");

// Don't forget to delete!
delete[] p2;
更好的选择是使用更安全的C++:

std::array<char, 256> p2 = {'b', 'b', 'c', 0};
p2[0] = 'a'; // "abc"

这将
p3
设置为字符串
“hello”

这会将位置
p3
点增加到内存中:

// *p3 = 'h';

p3++;
// *p3 = 'e';

p3++;
// *p3 = 'l';

p3++;
// *p3 = 'l';

要了解您为什么这样做:

char *p4 = 0;
char *p5 = NULL;
看看这个问题:


在C++中,我不会真的使用<代码>静态char */COS>s,但这里有一个愚蠢的例子:

void sc(char *first = NULL)
{
    static char *p = NULL;

    if(p == NULL)
        p = &first;

    // p will never change (even when sc() ends) unless you set it to NULL again:
    // p = NULL;
}

char initial_value;
sc(&initial_value);
sc();
sc();
// ...

这些都是检查
p
是否为
0
的方法;他们做同样的事情:

if(p)            // Short and simple.
if(p != 0)       // Easier to understand.
if(p != NULL)    // POINTERS ONLY.
在C++11中,您可以使用这种“更安全”的方式:


当您想要创建一个
char
s的“动态分配”数组时,您可以执行以下操作:

char *p2 = new char[4];
strcpy(p2, "abc");

// Don't forget to delete!
delete[] p2;
更好的选择是使用更安全的C++:

std::array<char, 256> p2 = {'b', 'b', 'c', 0};
p2[0] = 'a'; // "abc"

这将
p3
设置为字符串
“hello”

这会将位置
p3
点增加到内存中:

// *p3 = 'h';

p3++;
// *p3 = 'e';

p3++;
// *p3 = 'l';

p3++;
// *p3 = 'l';

要了解您为什么这样做:

char *p4 = 0;
char *p5 = NULL;
看看这个问题:


在C++中,我不会真的使用<代码>静态char */COS>s,但这里有一个愚蠢的例子:

void sc(char *first = NULL)
{
    static char *p = NULL;

    if(p == NULL)
        p = &first;

    // p will never change (even when sc() ends) unless you set it to NULL again:
    // p = NULL;
}

char initial_value;
sc(&initial_value);
sc();
sc();
// ...

OP使用的是
new
,所以它是。@Tomalak:这对这个问题有意义吗?因为在这些场景中,两种语言本质上是相同的?我本可以使用
malloc
而不是
p2
@muntoo中的new:我希望OP能帮我们解决这个问题。谢谢你的一匙羹。@QiangLi:在教学中,是的,它非常重要。对于新问题,开始一个新问题。答案出现后,不要在新问题中编辑。OP使用的是
new
,因此它是新的。@Tomalak:因为在这些场景中,两种语言本质上是相同的,这对问题的目的有关系吗?我本可以使用
malloc
而不是
p2
@muntoo中的new:我希望OP能帮我们解决这个问题。谢谢你的一匙羹。@QiangLi:在教学中,是的,它非常重要。对于新问题,开始一个新问题。答案出现后不要在新问题中编辑。当你说“基本上,它们都做相同的事情”时,你的意思是它们在所有情况下都是一样的吗?@QiangLi:除了没有定义
NULL
宏,或者被重新定义为其他东西(讨厌!)之外,那么在
p
是指针的所有情况下,是的都是相同的。@Liang:有些表达式检查指针是否为空,有些表达式检查指针指向的字符是否为0。试着找出哪个是哪个。当你说“基本上,它们都做相同的事情”时,你的意思是它们在所有情况下都是一样的吗?@QiangLi:除了
NULL
宏没有定义,或者被重新定义为其他东西(讨厌!)之外,那么在
p
是指针的所有情况下,是的都是相同的。@Liang:有些表达式检查指针是否为空,有些表达式检查指针指向的字符是否为0。试着找出哪个是哪个。试着否决这个答案(事实上,我是在最新的编辑之后做的)。