【问题标题】:Taking operators as argument variables将运算符作为参数变量
【发布时间】:2019-06-05 11:56:57
【问题描述】:

您好,我正在尝试创建一个只有四个运算符 +, -, /* 的简单计算器,但由于某种原因,我的实现不起作用。

我已经看到了几个有效的实现(包括一些最容易混淆的实现)但是我很想知道为什么以下工作?

#!/usr/bin/perl

my $num1 = $ARGV[0];
my $num2 = $ARGV[2];

my $operator = $ARGV[1];

print "$operator \n";

if($operator == '-')
{
  $num3 = $num1 - $num2;
  print "$num1 - $num2 = $num3\n";
} 
elsif($operator == "+")
{
  $num3 = $num1 + $num2;
  print "$num1 + $num2 = $num3\n";
}
elsif($operator == "/")
{
  $num3 = $num1 / $num2;
  print "$num1 / $num2 = $num3\n";
}
elsif($operator == "*")
{
  $num3 = $num1 * $num2;
  print "$num1 * $num2 = $num3\n";
}

此外,./expr.pl 7 * 2 命令返回以下内容:03.bellpaper.doc,这简直是深不可测。

【问题讨论】:

标签: perl


【解决方案1】:

始终以

开头您的文件
use strict;
use warnings;

在你的情况下,首先导致

Global symbol "$num3" requires explicit package name (did you forget to declare "my $num3"?) at script line 14.

添加缺少的my $num3声明后,我们得到

Argument "-" isn't numeric in numeric eq (==) at script line 13.

这是因为== 运算符是数值相等。它将两个操作数都转换为一个数字,该数字(如果您不启用警告)默默地为无效字符串提供0。这就是为什么($operand == '-') 最终会做0 == 0,这当然是真的。

要比较字符串,需要使用eq

if ($operand eq '-')

另见Relational Operators in perldoc perlop

./expr.pl 7 * 2 的问题在于 * 是一个通配符,您的 shell 会将其扩展为当前目录中所有文件的列表。您的程序将以./expr.pl 7 03.bellpaper.doc expr.pl whatever-else-is-in-the-current-directory 2 调用。

为了防止这种情况,您需要引用它,例如与./expr.pl 7 '*' 2./expr.pl 7 "*" 2./expr.pl 7 \* 2


其他说明:

  • $operand 是错误的名称。是运营商。这两个数字是操作数。
  • 来自$ARGV[...] 的手动分配可以合并为一个列表分配:my (...) = @ARGV;
  • 每个块中的print 语句几乎相同。我们可以将它们作为print "$num1 $operator $num2 = $num3\n" 拉出来(在确保$num3 确实设置后)。

这给了我们:

#!/usr/bin/perl
use strict;
use warnings;

my ($num1, $operator, $num2) = @ARGV;

print "$operator\n";

my $num3;
if ($operator eq '-') {
    $num3 = $num1 - $num2;
} elsif ($operator eq '+') {
    $num3 = $num1 + $num2;
} elsif ($operator eq '/') {
    $num3 = $num1 / $num2;
} elsif ($operator eq '*') {
    $num3 = $num1 * $num2;
}

if (defined $num3) {
    print "$num1 $operator $num2 = $num3\n";
}

【讨论】:

  • 您好,感谢您的建议,我已经对程序的运行进行了必要的编辑 - 您知道为什么当我只使用 * 运算符时可能会收到如此奇怪的输出吗?
  • @DavideLorino 您正在通过 shell 传递参数,* 是 shell 中的一个特殊字符(特别是一个 glob)。避免这种情况的最简单方法是在传递运算符时引用它们:'*'
  • 也许你应该提到使用调度表?
  • @ikegami 嗯,我想了想,但认为对于仍在尝试进行字符串比较的人来说,这可能是太多高级概念了。
【解决方案2】:

此外,命令 ./expr.pl 7 * 2 返回以下内容:03.bellpaper.doc,这简直是深不可测。

* 是一个 shell glob。您的 shell 将 * 替换为当前目录中每个文件的名称。程序的参数是7,然后是很多文件名,然后是2。这些文件名中的第一个由您的print "$operand\n" 行打印,然后由于$operand 与您正在检查的任何内容都不匹配,因此没有其他任何事情发生。

解决这个问题的方法是简单地在* 周围加上引号,或者以命令行以外的其他方式输入。

【讨论】:

    【解决方案3】:

    通常当我做这些事情时,我会创建一个名为choice 的整数变量,它会被传递到方法中。在该方法中,我将使用 if 和 else if 语句来解释参数。例如:0 = +、1 = -、2 = / 和 3 = *

    【讨论】:

    • 1.为什么是整数?将运算符直接作为字符串传递也同样有效,并且更容易调试/维护。 2.这并不能解决OP的问题。如何将运算符转换为数字?
    猜你喜欢
    • 1970-01-01
    • 2015-12-23
    • 1970-01-01
    • 2011-01-16
    • 2021-02-15
    • 2017-11-18
    • 2018-03-27
    • 2011-08-15
    • 2016-04-06
    相关资源
    最近更新 更多