每当我开始学习一门新的编程语言时,我都会专注于定义变量、编写语句和评估表达式。一旦我对这些概念有了大致的了解,通常就可以自己弄清楚其余部分。大多数编程语言都有一些相似之处,所以一旦你掌握了一门编程语言,学习下一门就变成了弄清楚独特的细节并识别差异的问题。
为了帮助我练习一门新的编程语言,我喜欢编写一些测试程序。我经常编写的一个示例程序是一个简单的“猜数字”游戏,其中计算机选择一个 1 到 100 之间的数字,并要求我猜。程序循环直到我猜对为止。这是一个非常简单的程序,你可以通过如下伪代码看到:
- 计算机选择一个 1 到 100 之间的随机数
- 循环直到我猜对随机数
- 计算机读取我的猜测
- 它告诉我我的猜测是太低还是太高
最近,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); 使用标准 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) |
循环直到我猜对随机数
循环通常使用诸如 while
或 do-while
之类的流程控制块来完成。 JavaScript 实现不使用循环,而是“实时”更新 HTML 页面,直到用户猜对正确的数字。 Awk 支持循环,但循环读取输入没有意义,因为 awk 基于数据管道,因此它从文件而不是直接从用户读取输入。
C | do { |
C++ | do { |
Rust | for line in std::io::stdin().lock().lines() { |
Java | while ( guess != NUMBER ) { |
Groovy | while ( … ) { |
Lua | while ( player.guess ~= number ) do |
计算机读取我的猜测
不同的编程语言处理输入的方式不同。因此这里有一些变化。例如,JavaScript 直接从 HTML 表单读取值,而 awk 从其数据管道读取数据。
C | scanf("%d", &guess); |
C++ | cin >> guess; |
Rust | let parsed = line.ok().as_deref().map(str::parse::<i64>); |
Java | guess = player.nextInt(); |
Groovy | response = reader.readLine() |
JavaScript | let myGuess = guess.value |
awk | guess = int($0) |
Lua | player.answer = io.read() |
告诉我我的猜测是太低还是太高
在这些类 C 编程语言中,比较相当一致,通常通过 if
语句。每种编程语言打印输出的方式略有不同,但 print 语句在每个示例中仍然可识别。
C | if (guess < number) { |
C++ | if ( guess > number) { cout << "Too high.\n" << endl; } |
Rust | _ if guess < random => println!("Too low"), |
Java | if ( guess > NUMBER ) { |
Groovy | if (guess < randomNumber) |
JavaScript | if (myGuess === randomNumber) { |
awk | if (guess < randomNumber) { |
Lua | if ( player.guess > number ) then |
那么非基于 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)] |
Python | if guess < random |
Elixir | cond do |
Bash | [ "0$guess" -lt $number ] && echo "Too low" |
Fortran | IF (GUESS.LT.NUMBER) THEN |
阅读更多
这个“猜数字”游戏是学习新编程语言时的一个很好的入门程序,因为它以非常直接的方式练习了几个常见的编程概念。 通过用不同的编程语言实现这个简单的游戏,你可以演示一些核心概念并比较每种语言的细节。
学习如何在 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 的语言
8 条评论