2

如何直接将值从菱形运算符传递给函数(子)?

我试过了:

#!/usr/bin/perl
use Math::Complex;

#quadraticEq - quadratic equation with parameters a ,b ,c
sub quadraticEq {
    print "\nx1= ", 
      ($_[1]*$_[1]-sqrt($_[1]*$_[1]-4*$_[0]*$_[2]))/(2*$_[0]),
      "\nx2= ",
      ($_[1]*$_[1]+sqrt($_[1]*$_[1]-4*$_[0]*$_[2]))/(2*$_[0]);
}

print 'Enter Numbers:';
quadraticEq(<>,<>,<>); #here

但是当我为每个函数参数输入数字时,我需要输入 EOF。它表现为@array=<>. 我希望它表现得像$var=<>. 所以输入应该是这样的:

Enter Numbers: 5 4 3
4

4 回答 4

6

在帮助您解决问题的同时,我将向您展示一些最佳实践...

#!/usr/bin/perl

use strict;     # strict/warnings helps detect lots of bugs and logic issues,
use warnings;   # so always use them

use Math::Complex; # WHITESPACE IS YOUR FRIEND

#quadraticEq - quadratic equation with parameters a ,b ,c

sub quadraticEq{
    # Shift out your subroutine variables one at a time, or assign them to a list.
    my ($a, $b, $c) = @_;

    print "\nx1= ", 
      ($b*$b-sqrt($b*$b-4*$a*$c))/(2*$a), # You're wrong on your formula btw
      "\nx2= ",
      ($b*$b+sqrt($b*$b-4*$a*$c))/(2*$a);
}

print 'Enter Numbers: ';

# Perl only supports reading in a line at a time, so... if you want all your
# inputs on one line, read one line.
# EDIT: That's not strictly true, since you can change the input record separator,
# but it's just simpler this way, trust me.

my $line = <>;

# Then you can split the line on whitespace using split.
my @coefficients = split /\s+/, $line;

# You should check that you have at least three coefficients and that they
# are all defined!

quadraticEq(@coefficients);
于 2011-03-17T16:26:46.460 回答
5

函数参数列表中的裸<>操作符总是在列表上下文中调用。但是有很多方法可以强制使用您想要的标量上下文:

quadraticEq(scalar <>, scalar <>, scalar <>);
quadraticEq("" . <>, "" . <>, "" . <>);
quadraticEq(0 + <>, 0 + <>, 0 + <>);  # if you want to evaluate as numbers anyway

请注意,<>在标量上下文中,将从输入读取到下一个“记录分隔符”。默认情况下是系统的换行符,因此上面代码的默认行为是从每一行读取单独的值。如果(正如原始帖子所暗示的那样)输入是空格分隔的并且都在一行上,那么您将需要:

  1. $/ = " "在调用之前将记录分隔符设置为空格 ( ) <>,或
  2. 使用不同的方案,例如split将一行输入解析为单独的值
# 读取一行输入并提取 3 个空格分隔的值
二次方程(拆分/\s+/,<>,3);

对于这样的问题,我几乎总是选择#2,但是有不止一种方法可以做到这一点。

于 2011-03-17T16:20:56.717 回答
2

通常,当向子例程传递值时,Perl 使用列表上下文,所以你正在做的就是使用 <> 与

my @args = (<>, <>, <>);

这显然不是你想要的!

scalar您可以使用关键字强制标量上下文:

my @args = ( scalar <>, scalar <>, scalar <>); # read one

或者,将它们全部读入变量,以便人们知道您的意图:

my $first = <>;
my $second = <>;
my $third = <>;

顺便说一句,在使用它们之前,您应该真正从 @_ 中解析出参数。它将使您的功能更加易于理解。一个例子:

sub quadratic2 {
    my ($a, $b, $c) = @_;
    ... # now use the actual symbols instead of array indexes
}
于 2011-03-17T16:24:18.303 回答
2
quadraticEq(map scalar <>, 1..3);

另请参阅perldoc -f readline

于 2011-03-17T16:27:36.897 回答