編程語言比較:C 和 Go
Go 是一種現(xiàn)代編程語言,它很大程度上源自于 C 編程語言。因此,對于寫 C 程序的程序員來說,Go 應(yīng)該會感覺很熟悉。Go 讓編寫新程序變得容易,同時讓 C 程序員感覺熟悉,但避免了 C 編程語言的許多常見陷阱。
本文比較了一個簡單的 C 和 Go 程序,該程序?qū)?shù)字從一相加到十。由于這個程序只使用了小的數(shù)值,所以結(jié)果不會變得太大,因此只使用了普通的整數(shù)變量。像這樣的循環(huán)在編程中非常常見,所以這個簡單的程序很容易比較 C 和 Go。
如何在 C 中執(zhí)行循環(huán)
C 語言中最基本的循環(huán)是 for
循環(huán),它允許你對一組值進行迭代。for
循環(huán)的基本語法是:
for (起始條件 ; 結(jié)束條件 ; 每次迭代后執(zhí)行的操作) { 循環(huán)內(nèi)要執(zhí)行的內(nèi)容 ; }
你可以編寫一個 for
循環(huán),以打印從 1 到 10 的數(shù)字,將起始條件設(shè)置為 count = 1
,將結(jié)束條件設(shè)置為 count <= 10
。這樣就以 count
變量等于 1 時開始循環(huán)。結(jié)束條件意味著只要 count
變量小于或等于 10 ,循環(huán)就會繼續(xù)。
每次迭代之后,你使用 count = count + 1
將 count
變量的值增加 1。在循環(huán)內(nèi)部,你可以使用 printf
打印 count
變量的值:
for (count = 1; count <= 10; count = count + 1) {
printf("%d\n", count);
}
C 程序中常見的慣例是 ++
,它表示 “將某個值加一”。如果你寫 count++
,那就相當(dāng)于 count = count + 1
。大多數(shù) C 程序員會使用 count++
來編寫 for
循環(huán)中每次迭代后要執(zhí)行的操作,像這樣:
for (count = 1; count <= 10; count++) {
printf("%d\n", count);
}
這是一個示例程序,將從 1 到 10 的數(shù)字相加,然后打印結(jié)果。使用 for
循環(huán)對數(shù)字進行迭代,但不要打印數(shù)字,而是將數(shù)字添加到 sum
變量中:
#include <stdio.h>
int main() {
int sum;
int count;
puts("adding 1 to 10 ..");
sum = 0;
for (count = 1; count <= 10; count++) {
sum = sum + count;
}
這個程序使用了兩個不同的 C 函數(shù)來向用戶打印結(jié)果。puts
函數(shù)打印引號中的字符串。如果你需要打印純文本,使用 puts
是個不錯的選擇。
printf
函數(shù) 使用特殊字符在格式字符串中打印格式化的輸出。printf
函數(shù)可以打印許多不同種類的值。關(guān)鍵字 %d
打印十進制(整數(shù))值。
如果你編譯并運行這個程序,你會看到這個輸出:
adding 1 to 10 ..
The sum is 55
如何在 Go 中執(zhí)行循環(huán)
Go 提供了與 C 中非常相似的 for
循環(huán)。C 程序中的 for
循環(huán)可以直接轉(zhuǎn)換為 Go 的 for
循環(huán),并具有相似的表示形式:
for count = 1; count <= 10; count++ {
fmt.Printf("%d\n", count)
}
使用這個循環(huán),你可以直接轉(zhuǎn)換為 Go 的示例程序:
package main
import "fmt"
func main() {
var sum, count int
fmt.Println("adding 1 to 10 ..")
for count = 1; count <= 10; count++ {
sum = sum + count
}
fmt.Printf("The sum is %d\n", sum)
}
雖然上述方式在 Go 中是正確的,但它并不是最常用的 Go 寫法。采用慣例是“使用與本地語言為人所知的表達方式”。任何語言的目標都是高效的溝通,編程語言也不例外。在不同的編程語言之間進行轉(zhuǎn)換時,重要的是意識到盡管物似而意不同,一種編程語言中的典型寫法在另一種編程語言中可能不完全相同。
為使用更符合慣例的 Go,你可以進行幾個小修改:
- 通過使用
+=
操作符來將sum = sum + count
更簡潔地表達為sum += count
。 - 通過使用 分配并推斷類型運算符 來表達
count := 1
而不是var count int
跟著count = 1
。:=
語法同時定義并初始化count
變量。 - 將
count
的聲明移到for
循環(huán)的頭中。這減少了一些認知負擔(dān),也通過減少程序員在任何時候都必須心里記著的變量數(shù)目來提高可讀性。這個更改還通過在最接近其使用的地方和最小的范圍中聲明變量來增加安全性,從而減少了在代碼不斷演進的過程中對變量進行意外操作的可能性。
上述改動的組合將產(chǎn)生以下代碼:
package main
import "fmt"
func main() {
fmt.Println("adding 1 to 10 ..")
var sum int
for count := 1; count <= 10; count++ {
sum += count
}
fmt.Printf("The sum is %d\n", sum)
}
你可以使用這個 Go.dev 的 鏈接 在 Go 試驗場中嘗試這個示例程序。
C 和 Go 相似但不同
通過在兩種編程語言中編寫相同的程序,你可以看到 C 和 Go 這兩種語言雖然相似但仍然不同。將從 C 轉(zhuǎn)換到 Go 時需要注意以下幾點:
- 在 C 中,每個程序指令都必須以分號結(jié)尾。這告訴編譯器一個語句在哪里結(jié)束,下一個在哪里開始。在 Go 中,分號是有效的,但幾乎總是可以推斷出來。
- 雖然大多數(shù)現(xiàn)代 C 編譯器會為你將變量初始化為零值,但 C 語言規(guī)范指出,變量得到的是內(nèi)存中的任意值。Go 值總是初始化為其零值。這有助于使 Go 成為一種更具內(nèi)存安全的語言。這種差異在使用指針時變得更加有趣。
- 注意 Go 程序包對導(dǎo)入標識符的使用方式。例如,
fmt
是一個實現(xiàn)格式化輸入和輸出的函數(shù),類似于 C 中的stdio.h
中的printf
和scanf
。fmt
程序包在 pkg.go.dev/fmt 中有文檔描述。 - 在 Go 中,
main
函數(shù)總是以退出代碼 0 返回。如果你希望返回其他值,你必須調(diào)用os.Exit(n)
,其中n
通常為 1 以表示錯誤。這可以從任何地方調(diào)用,不僅僅是main
函數(shù),來終止程序。你可以在 C 中使用在stdlib.h
中定義的exit(n)
函數(shù)來實現(xiàn)相同的效果。