每当我开始学习一门新的编程语言时,我都会专注于定义变量、编写语句和评估表达式。一旦我对这些概念有了大致的了解,我通常就可以自己弄清楚剩下的内容。大多数编程语言都有一些相似之处,所以一旦你掌握了一门编程语言,学习下一门语言就只是弄清楚独特的细节并识别差异的问题了。
为了帮助我练习新的编程语言,我喜欢编写一些测试程序。我经常编写的一个示例程序是一个简单的“猜数字”游戏,其中计算机选择一个介于 1 到 100 之间的数字,并要求我猜。程序循环直到我猜对为止。这是一个非常简单的程序,你可以使用像这样的伪代码看到:
- 计算机选择一个介于 1 到 100 之间的随机数
- 循环直到我猜到随机数
- 计算机读取我的猜测
- 它告诉我我的猜测是太低还是太高
最近,Opensource.com 运行了一个系列文章,用不同的语言编写了这个程序。这是一个有趣的机会来比较如何在每种语言中做同样的事情。我还发现大多数编程语言做事方式相似,所以学习下一门编程语言主要是学习它的差异。
C 是一种早期的通用编程语言,于 1972 年由 Dennis Ritchie 在贝尔实验室创建。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 条评论