不同编程语言如何实现相同的功能

通过编写一个简单的游戏来比较 13 种不同的编程语言。
82 位读者喜欢这篇文章。
3 cool machine learning projects using TensorFlow and the Raspberry Pi

Opensource.com

每当我开始学习一门新的编程语言时,我都会专注于定义变量、编写语句和评估表达式。一旦我对这些概念有了大致的了解,通常就可以自己弄清楚其余部分。大多数编程语言都有一些相似之处,所以一旦你掌握了一门编程语言,学习下一门就变成了弄清楚独特的细节并识别差异的问题。

为了帮助我练习一门新的编程语言,我喜欢编写一些测试程序。我经常编写的一个示例程序是一个简单的“猜数字”游戏,其中计算机选择一个 1 到 100 之间的数字,并要求我猜。程序循环直到我猜对为止。这是一个非常简单的程序,你可以通过如下伪代码看到:

  1. 计算机选择一个 1 到 100 之间的随机数
  2. 循环直到我猜对随机数
    1. 计算机读取我的猜测
    2. 它告诉我我的猜测是太低还是太高

最近,Opensource.com 运行了一个系列文章,用不同的语言编写了这个程序。这是一个有趣的机会,可以比较如何在每种语言中做同样的事情。我还发现,大多数编程语言的工作方式都非常相似,因此学习下一门编程语言主要就是学习它的差异。

C 是一种早期的通用编程语言,由 Dennis Ritchie 于 1972 年在贝尔实验室创建。C 证明了其受欢迎程度,并迅速成为 Unix 系统上的标准编程语言。由于其受欢迎程度,许多其他编程语言采用了类似的编程语法。这就是为什么如果你已经知道如何用 C 编程,学习 C++、Rust、Java、Groovy、JavaScript、awk 或 Lua 会更容易。

例如,看看这些不同的编程语言如何实现“猜数字”游戏的主要步骤。我将跳过一些周围的代码,例如分配临时变量,以专注于基本知识的相似之处或不同之处。

计算机选择一个 1 到 100 之间的随机数

你可以在这里看到很多相似之处。大多数编程语言都使用类似 rand() 的函数生成随机数,你可以自己将其放入一个范围内。其他语言使用特殊的函数,你可以在其中指定随机值的范围。

C 使用 Linux getrandom 系统调用

getrandom(&randval, sizeof(int), GRND_NONBLOCK);

number = randval % maxval + 1;




使用标准 C 库

number = rand() % 100 + 1;
C++ int number = rand() % 100+1;
Rust let random = rng.gen_range(1..101);
Java private static final int NUMBER = r.nextInt(100) + 1;
Groovy int randomNumber = (new Random()).nextInt(100) + 1
JavaScript const randomNumber = Math.floor(Math.random() * 100) + 1
awk randomNumber = int(rand() * 100) + 1
Lua number = math.random(1,100)

循环直到我猜对随机数

循环通常使用诸如 whiledo-while 之类的流程控制块来完成。 JavaScript 实现不使用循环,而是“实时”更新 HTML 页面,直到用户猜对正确的数字。 Awk 支持循环,但循环读取输入没有意义,因为 awk 基于数据管道,因此它从文件而不是直接从用户读取输入。

C do {



} while (guess != number); 
C++ do {

… 

} while ( number != guess ); 
Rust for line in std::io::stdin().lock().lines() {



break;

Java while ( guess != NUMBER ) {



Groovy      while ( … ) {



break;

Lua  while ( player.guess ~= number ) do



end

计算机读取我的猜测

不同的编程语言处理输入的方式不同。因此这里有一些变化。例如,JavaScript 直接从 HTML 表单读取值,而 awk 从其数据管道读取数据。

C scanf("%d", &guess); 
C++ cin >> guess; 
Rust let parsed = line.ok().as_deref().map(str::parse::<i64>);

if let Some(Ok(guess)) = parsed {



Java guess = player.nextInt(); 
Groovy response = reader.readLine()

int guess = response as Integer 
JavaScript let myGuess = guess.value 
awk guess = int($0) 
Lua player.answer = io.read()

player.guess = tonumber(player.answer) 

告诉我我的猜测是太低还是太高

在这些类 C 编程语言中,比较相当一致,通常通过 if 语句。每种编程语言打印输出的方式略有不同,但 print 语句在每个示例中仍然可识别。

C     if (guess < number) {

      puts("Too low");

    }

    else if (guess > number) {

      puts("Too high");

    }



  puts("That's right!");
  
C++   if ( guess > number) { cout << "Too high.\n" << endl; }

  else if ( guess < number ) { cout << "Too low.\n" << endl; }

  else {

    cout << "That's right!\n" << endl;

    exit(0);

  }
  
Rust                 _ if guess < random => println!("Too low"),

                _ if guess > random => println!("Too high"),

                _ => {

                    println!("That's right");

                    break;

                } 
Java             if ( guess > NUMBER ) {

                System.out.println("Too high");

            } else if ( guess < NUMBER ) {

                System.out.println("Too low");

            } else {

                System.out.println("That's right!");

                System.exit(0);

            } 
Groovy                   if (guess < randomNumber)

                      print 'too low, try again: '

                  else if (guess > randomNumber)

                      print 'too high, try again: '

                  else {

                      println "that's right"

                      break

                  } 
JavaScript       if (myGuess === randomNumber) {

        feedback.textContent = "You got it right!"

      } else if (myGuess > randomNumber) {

        feedback.textContent = "Your guess was " + myGuess + ". That's too high. Try Again!"

      } else if (myGuess < randomNumber) {

       feedback.textContent = "Your guess was " + myGuess + ". That's too low. Try Again!"

     } 
awk             if (guess < randomNumber) {

                printf "too low, try again:"

            } else if (guess > randomNumber) {

                printf "too high, try again:"

            } else {

                printf "that's right\n"

                exit

            } 
Lua   if ( player.guess > number ) then

    print("Too high")

  elseif ( player.guess < number) then

    print("Too low")

  else

    print("That's right!")

    os.exit()

  end 

那么非基于 C 的语言呢?

不基于 C 的编程语言可能非常不同,并且需要学习特定的语法才能完成每个步骤。 Racket 派生自 Lisp 和 Scheme,因此它使用 Lisp 的前缀表示法和大量括号。 Python 使用空格而不是括号来指示循环之类的块。 Elixir 是一种具有自己语法的函数式编程语言。 Bash 基于 Unix 系统的 Bourne shell,它本身借鉴了 Algol68,并支持额外的简写符号,例如 && 作为“and”的一种变体。 Fortran 是在使用穿孔卡输入代码时创建的,因此它依赖于 80 列的布局,其中某些列具有重要意义。

作为这些其他编程语言如何不同的一个例子,我将仅比较“if”语句,该语句查看一个值是小于还是大于另一个值,并向用户打印适当的消息。

Racket   (cond [(> number guess) (displayln "Too low") (inquire-user number)]

        [(< number guess) (displayln "Too high") (inquire-user number)]

        [else (displayln "Correct!")])) 
Python     if guess < random

        print("Too low")

    elif guess > random

        print("Too high")

    else

        print("That's right!") 
Elixir     cond do

      guess < num ->

        IO.puts "Too low!"

        guess_loop(num)

      guess > num ->

        IO.puts "Too high!"

        guess_loop(num)

      true ->

        IO.puts "That's right!"

    end 
Bash         [ "0$guess" -lt $number ] && echo "Too low"

        [ "0$guess" -gt $number ] && echo "Too high" 
Fortran       IF (GUESS.LT.NUMBER) THEN

         PRINT *, 'TOO LOW'

      ELSE IF (GUESS.GT.NUMBER) THEN

         PRINT *, 'TOO HIGH'

      ENDIF 

阅读更多

这个“猜数字”游戏是学习新编程语言时的一个很好的入门程序,因为它以非常直接的方式练习了几个常见的编程概念。 通过用不同的编程语言实现这个简单的游戏,你可以演示一些核心概念并比较每种语言的细节。

学习如何在 C 和类 C 语言中编写“猜数字”游戏

  • C,作者:Jim Hall
  • C++,作者:Seth Kenlon
  • Rust,作者:Moshe Zadka
  • Java,作者:Seth Kenlon
  • Groovy,作者:Chris Hermansen
  • JavaScript,作者:Mandy Kendall
  • awk,作者:Chris Hermansen
  • Lua,作者:Seth Kenlon

以及非基于 C 的语言

  • Racket,作者:Cristiano L. Fontana
  • Python,作者:Moshe Zadka
  • Elixir,作者:Moshe Zadka
  • Bash,作者:Jim Hall
  • Fortran,作者:Jim Hall
标签
photo of Jim Hall
Jim Hall 是一位开源软件倡导者和开发者,最出名的是在 GNOME 中进行可用性测试,以及作为 FreeDOS 的创始人和项目协调员。

8 条评论

老实说,我也很想在这个比较中看到 Go 语言 :)

这是一个使用声明式高阶技术的 #rakulang 版本,展示了该语言的 3 个主要特性:惰性序列、ad-hoc 角色混合和控制流语句的后缀形式。

my \n = (1..100).pick;

my %a =
Less => "Too Low" but False,
More => "Too High" but False,
Same => "That's right!";

$*IN.lines.first: { .say and .so with %a{ .Int cmp n } }

Raku 也是你所说的 C 风格语言,因此它提供了常见的控制结构,包括 switch、while、until(甚至“loop”,它无条件地永远循环;无需为编写“while true”感到内疚)。

Raku 是你从未意识到自己想要的语言。
https://raku.perl5.cn/
#raku on freenode
Pingback: https://twitter.com/liztormato/status/1379129214239174657

令人遗憾的是,一种历史悠久但已被广泛弃用的类 C 语言 (PERL) 可以用更少的代码更优雅地完成所有这些操作。有人能用一行代码做到这一点吗?

超过 1500 种语言的相同程序怎么样? http://99-bottles-of-beer.net/
Perl 和 vi 版本太棒了!谁知道你可以在 vi 中运行程序。

在“循环直到我猜对随机数”部分中,我将使用 while 循环而不是 do-while 循环来编写循环代码。通常认为如果可能的话应该避免 do-while 循环,我同意。 C++ 也是如此!

我想这对于你的收藏来说是一件稀有物品:Ada 版本

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Numerics.Discrete_Random;

procedure Main is
type Game_Value is range 1 .. 100;

package Game_Io is
new Ada.Text_IO.Integer_IO (Game_Value);

package Game_Random is
new Ada.Numerics.Discrete_Random (Game_Value);

Random_Generator : Game_Random.Generator;

Guess_Me : constant Game_Value := Game_Random.Random (Random_Generator);
User_Guess : Game_Value;
begin
loop
Game_Io.Get (User_Guess);

if User_Guess > Guess_Me then
Put_Line ("Too large");

elsif User_Guess < Guess_Me then
Put_Line ("Too small");

else
Put_Line ("Correct!");
exit;
end if;
end loop;
end Main;

Creative Commons License本作品根据 Creative Commons Attribution-Share Alike 4.0 International License 获得许可。
© . All rights reserved.