计划:带有多个程序的条件if语句

4
我正在尝试弄清楚如何使我的if语句执行多个任务,但仅返回一个结果,如果这有意义的话。另外,我不知道如何在同一行中打印字符串和变量。
例如,在Scheme中如何做到这一点(以下是Java):
if(num < x){
  num++;
  x = 0;
  System.out.println("The value of x is " + x " and num is now" + num);
}

否则 System.out.println("错误");

这是我尝试过的:

(if (< num x) 
( (define num (+ 1 num))
   (define x 0)
   ;idk how to print it
   )
"error";else
)
6个回答

3

您可以使用 begin 来对一系列表达式进行求值,并返回最后一个表达式的结果。同时,您也可以使用 printf 来打印输出:

(if (< num x)
    (begin
      (set! num (add1 num))
      (set! x 0)
      (printf "The value of x is ~a and num is now ~a\n" x num))
    "error")

然而请记住,在Racket中使用set!来覆盖(改变)变量是不被鼓励的。更好的做法是返回新值。在没有稍微大一点的示例和更多背景信息的情况下,很难向您展示如何做到这一点。无论如何,如果您感兴趣,这可能应该是自己的新问题。

1
我先说一下,因为我不懂Java,所以不太确定你想让你的代码做什么。
但是我可以说的是,内部定义表达式肯定会让你困惑。在Racket中,通常不能在表达式中定义全局变量,而应该使用类似以下形式的本地绑定:
(let ([identifier expression]
        ...
        [id-n expression-n])
    body-expressions)

这种方式用指定的绑定来评估身体表达式,最后一个评估结果作为整个let表达式的结果返回。这是一个执行多项操作并返回一个结果的方法。在(if test consequent alternative)语句的上下文中,您可以使用(begin expression...)形式将多个表达式组合在一起(例如作为一个consequent),该形式执行所有表达式并返回最后一个表达式的结果。另一种选择是使用cond表达式,其形式如下:

(cond [test conequents]
        ...
        [test-n cons-n]
        [else expression])

每个测试都可以有多个结果,因此使用几个开始可能会更清晰。
此外,如果您真的想改变num和x的值,您将使用(set!id value)过程,但在Racket中,函数递归形式是首选的。
超出这些点需要我猜测,但看起来您正在一个接受两个参数x和num的函数中工作,并希望增加num的值直到达到x的值,在此过程中打印x和num的值,如果给定大于num的x值,则要返回错误。
在Racket中,您可以像这样递归地执行此操作:
(define inc-print ;defining inc-print
  (lambda (x num) ;a function of two arguments
    (cond [(> num x) "error"]
          [(< num x)
           ;the printf command takes a string and prints it.
           ;you can add values to the string by inserting ~a's followed by as many
           ;expressions as ~a's
           ;\n is shorthand for (newline) so that subsequent calls to printf print on a newline
           (printf "The value of x is ~a and num is now ~a\n" x num)
           ;a recursive call to inc-print with num incremented by 1 and x the same
           (inc-print x (+ num 1))]
          [else num])))

例子:
> (inc-print 5 2)
The value of x is 5 and num is now 2
The value of x is 5 and num is now 3
The value of x is 5 and num is now 4
5

如果这个回答解决了您的问题,请告诉我!


0

我没有Java的经验,但我猜这就是你要找的。

class IfElseDemo {
public static void main(String[] args) {

    int testscore = 76;
    char grade;

    if (testscore >= 90) {
        grade = 'A';
    } else if (testscore >= 80) {
        grade = 'B';
    } else if (testscore >= 70) {
        grade = 'C';
    } else if (testscore >= 60) {
        grade = 'D';
    } else {
        grade = 'F';
    }
    System.out.println("Grade = " + grade);
}

}

更多细节在这里:

https://docs.oracle.com/javase/tutorial/java/nutsandbolts/if.html

为什么这段代码不能按预期工作?


0

如果你想要结合ifdefine,你可以使用let。 这是非常常见的,所以cond会让整个过程更简单:

(if (< num x) 
    (let () ; use let in order to use define in an expression context
      (define num (+ 1 num))
      (define x 0)
      (displayln (list 'num num 'x x))
      x)
    (displayln "error"))

(cond
  [(< num x) (define num (+ 1 num))
             (define x 0)
             (displayln (list 'num num 'x x))
             x]
  [else     (displayln "error")])

0
首先,在Scheme中使用display在终端上显示文本,在#!racket中,您也可以使用displayln以及许多其他更专业的过程
在Java(以及许多其他C后代/方言)中,if的格式几乎与Scheme相同:
if ( x < 3 )
    return 0;
else
    return 10;

在Scheme中看起来非常相似:
(if (< x 3)
    0
    10)

如果你需要执行更多需要一条语句的操作,你需要将它们分组。在Java(以及所有C衍生语言)中,我们通过用大括号{}将多个语句组合成一个来实现。例如:

{
    System.out.println("Side effect " + localVar);
    return 10;
}

上述内容是在任何语句允许的地方都是有效的块。在Scheme中,您可以使用begin来表示块。

(begin (display "Side effect\n")
       10)

过程体和let形式被认为具有显式的begin。这意味着它允许多个表达式。但只有尾部表达式被视为“返回”。

Scheme中许多特殊形式都有显式的begin。在Java中,您没有这样的选项,因为在这些情况下,您必须使用花括号。例如,过程体:

(lambda (arg)
  (define test 10) ; one expression
  (+ test arg))    ; another expression

letlet*letrec等仅仅是匿名过程调用,因此它们的主体继承了lambda的显式开始。在cond的结果和替代方案中,你可以使用它们:

(cond ((hash-ref hash test) #f)
      ((> test 10) (hash-set! hash test #t) #t)    ; two expressions consequent
      (else        (hash-set! hash test #t) test)) ; two expressions alternative

cond通常是一个宏,可以转换为if。它们之间的区别在于隐式开始和支持多个术语。因此,在需要显式开始或代替嵌套的if时,使用cond很好。结果是更易读的代码,更加平坦。上面的cond可以用if这样写:

(if (hash-ref hash test) 
    #f
    (if (> test 10)
        (begin  
          (hash-set! hash test #t) ; one expression
          #t)                      ; another expression (tail)
        (begin 
          (hash-set! hash test #t) ; one expression
          test)))                  ; another expression (tail)

正如您所看到的,cond 更加紧凑,如果您熟悉 Scheme,那么它更容易阅读。正确的缩进非常重要,因此使用可以自动缩进的 IDE 将有助于您编写其他 Scheme 程序员可以阅读的代码。由于您标记了 racket,因此您可以使用 DrRacket 并经常按下 CTRL + i


0

我知道我晚了7年,但是因为我也遇到了同样的问题,所以刚刚看到了这个问题。我正在使用Guile,我查阅了手册并找到了以下内容:

当你写一个没有备选项(“单臂if”)的‘if’时,你表达的部分是你不关心表达式的返回值(或值)。因此,你更感兴趣的是评估结果表达式的效果。(按照惯例,我们使用“语句”一词来指代为了效果而不是值而评估的表达式)。

在这种情况下,用这些特殊形式‘when’和‘unless’表达这些意图被认为更清晰。作为额外的奖励,这些形式接受多个要评估的语句,这些语句隐含地包含在‘begin’中。

因此,与其他答案建议的使用ifcond不同,您可以执行以下操作:

(when (< num x)          ;; if (num < x) {
  (set! num (+ num 1))   ;;   num++;
  (set! x 0)             ;;   x = 0;
  (display "..."))       ;;   print("...");
                         ;; }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接