例如,请考虑以下代码。指针p
指向包含非零值的变量a
。意思是,条件应该是真的。所以,如果程序返回1,我没有问题。
#include <iostream>
int main()
{
int *p, a = 1;
p = &a;
if(p)
{
return 1;
}
return 0;
}
但对于以下程序,结果也一样。虽然此时指针指向一个包含0的变量。因此,条件应为false,但不是。
#include <iostream>
int main()
{
int *p, a = 0;
p = &a;
if(p)
{
return 1;
}
return 0;
}
那么,我错过了什么?为什么条件总是返回真实?我假设指针与它指向的值无关。相反,它是在其他东西的基础上评估条件,我想知道这个特定的原因。
答案 0 :(得分:6)
空指针被隐式转换为布尔值false,而非空指针转换为true。从C ++ 11标准,有关布尔转换的部分:
算术,无范围枚举,指针或指向成员类型的指针的prvalue可以转换为bool类型的prvalue。零值,空指针值或空成员指针值转换为false;任何其他值都转换为true。类型为std :: nullptr_t的prvalue可以转换为bool类型的prvalue;结果值为false
答案 1 :(得分:2)
使用此:
if(*p)
而不是
if(p)
*p
取消引用指针,产生值。 p
只是一个保存另一个变量地址的对象。
答案 2 :(得分:1)
这里的问题在于你的if语句:
if (p)
这是因为在p
中,您存储了值&a
,这是变量a
的地址,其中存储了值,不变量本身。
我编译程序并运行它时,a
的地址为0x7fff0d9fd274
,而不为零。 if语句的条件中的任何值将始终计算为true
如果该值不为零。因此,即使a
中的值发生更改,您的条件也会得到验证,因为您的编译器不会甚至查看a
的值;它只是检查存储为p
中的值的地址是否为零,而不是。因此,if语句始终为true,因此程序会终止并始终返回非零状态。
要解决此问题,您应该使用*p
代替p
。此语法告诉编译器获取指针p
存储的地址中的值,该值在第二个程序中为零。
将第二个程序中的if条件更改为:
if (*p)
将以零状态终止程序,就像你想要的那样。
希望这有帮助!
答案 3 :(得分:1)
if (p)
确实返回true,因为if (p)
是if (p != nullptr)
的捷径。
p
包含变量a
的内存地址。在我的机器0x29fef8
。由于nullptr
相当于0
而p不是0
,因此条件if (p != nullptr)
的计算结果为true。因此,条件总是返回true。
答案 4 :(得分:0)
在C中,指针与两个运算符的变量相关: takeaddress ,由&符号或&amp; 表示,取消引用,由星号字符表示,或者*****。
首先,您应该记住指针保存内存位置的地址。那么,你的路线
p =&amp; a;
将指针变量p
放入int变量a
的地址。该地址肯定不为空,因为a是现有变量,具有实际地址。
这就是为什么您对p
值的测试始终适用的原因。
如果您想测试p
所占地址的内容 - 即a
的值,则应取消引用它。换句话说,您的代码应该是:
#include <iostream>
int main()
{
int *p, a = 0;
p = &a;
if(*p)
{
return 1;
}
return 0;
}
答案 5 :(得分:0)
if (p)
将始终评估为true,直到p
未指向任何内容(地址0x)。我认为您真正想要做的是if (*p)
,因此您要评估地址p
指向的值。 *
用于访问地址中的信息。
请记住,指针保留地址而不是值,因此p = &a
和*p = a