有人能给我解释一下perl程序的行为吗

有人能给我解释一下perl程序的行为吗,perl,logical-operators,Perl,Logical Operators,我编写了这个perl程序,我希望输出如下 $a=""; $b="n"; $c = !$a; $d = !$b; print $c , "\n" , $d; if($d == 0){ print "zero"; } 但它会打印出来 1 0Zero 有人能解释一下为什么会这样吗???Perl中的变量根据上下文被视为数字或字符串。如果在分配给某个对象时没有将其视为数字,则在打印时Perl会将其视为字符串 因此,错误值为(我添加了强调): 数字0、字符串“0”和“”、空列表()和未定义

我编写了这个perl程序,我希望输出如下

$a="";
$b="n";
$c = !$a;
$d = !$b;
print $c , "\n" , $d;
if($d == 0){
    print "zero";
}
但它会打印出来

1  
0Zero

有人能解释一下为什么会这样吗???

Perl中的变量根据上下文被视为数字或字符串。如果在分配给某个对象时没有将其视为数字,则在打印时Perl会将其视为字符串

因此,错误值为(我添加了强调):

数字0、字符串“0”和“”、空列表()和未定义 在布尔上下文中都为false。所有其他值均为真。 对真值的否定!或not返回一个特殊的假值。 当作为字符串计算时,它被视为“”,但作为数字,它 被视为0。大多数返回true或false的Perl运算符的行为 这边走

所以,这里的问题是
是逻辑运算符而不是算术运算符。因此,它返回一个逻辑上错误的值,该值根据上下文以不同的方式表示

如果你想确保某个东西被当作一个数字,你有几个选择。您可以执行一个算术运算,这将使Perl考虑结果的个数:

1  
zero
您可以使用
sprintf
printf
显式控制显示:

$d=!$b+0;
print $d;
或者您可以使用
int

printf '%d', $d;

(注意:这一切看起来可能有点复杂。但它的设计目的是让语言只做你想做的事情,而你不必考虑它。通常情况下,它是这样做的。只有偶尔的边缘情况下,你需要做一些Perl默认行为以外的事情。)

$b
的计算结果为空字符串
,因为当通过
print()
“$bool”
或某些其他字符串操作进行字符串化时,假值不表示为零

print int $d;
输出

$a="";
$b="n";
$c = !$a;
$d = !$b;
print $c , "\n" , $d;
if($d == 0){
    print "zero";
}

use Data::Dumper;
print Dumper {
  '$a' => $a,
  '$b' => $b,
  '$c' => $c,
  '$d' => $d,
  '$d == 0' => $d == 0,
};
在你的阅读中

在布尔上下文中,数字0、字符串“0”和“”、空列表()和undef都为false。所有其他值均为真。对真值的否定!或not返回一个特殊的假值。当作为字符串计算时,它被视为“”,但作为数字,它被视为0。大多数返回true或false的Perl运算符都是这样操作的


这就是你的经历
$a
为假值,因此
$分配给
$c
的a
成为真值,相应地打印为
1
$b
是一个真值,因此
$分配给
$d
的b
,成为该特殊假值。在print语句(
print$c,“\n”,$d;
)中,将在字符串上下文中对其求值,因此将打印空字符串。if语句(
$d==0
)在数字上下文中对其求值,因此它是一个
0
,因此打印
0

Perl运算符,如
为false返回一个特殊值:在字符串上下文中使用时为“”,在数字上下文中使用时为0

因此,当您打印它时,它是“”,而不是“0”。但是,如果您尝试将其用作数字,它不会像“”那样发出警告。比较:

$VAR1 = {
      '$d == 0' => 1,  # boolean true
      '$b' => 'n',
      '$d' => '',      # boolean false
      '$c' => 1,
      '$a' => ''
    };


但是为什么它不为$Db打印0,因为
$d
包含一个空字符串,而不是零。强制数字解释的方法是说
0+$d
。以及
的含义基本上是“1”;否则为空字符串”。这有点令人惊讶,但与Perl中布尔真值的定义一致。@nikhilmehta,补充了更多细节。
perl -wle'$false = !1; print "string: ", $false, " number: ", 0+$false'
string:  number: 0
perl -wle'$empty = ""; print "string: ", $empty, " number: ", 0+$empty'
Argument "" isn't numeric in addition (+) at -e line 1.
string:  number: 0