以下内容为本人的学习笔记,如需要转载,请声明原文链接微信公众号「ENG八戒」https://mp.weixin.qq.com/s/U6jIT837x5Yxe6Ev1aMDsA

使用一个简单的计数程序将古老的 C 语言与现代 Go 进行比较。

Go 是一种现代编程语言,追溯其历史大部分源自编程语言 C。所以,任何熟悉 C 语言的开发者都可能会觉得 Go 很熟悉。C 程序员使用 Go 编写新程序变得容易,同时避免了 C 编程语言的许多常见缺陷。

下面通过实现一个简单的加法逻辑,来比较 C 和 GO 的区别。该程序将数字从一加到十,计算过程和结果数值都比较小,所以代码仅使用普通整数变量。像这样的循环逻辑在编程中很常见,所以对比效果会显而易见。

C 语言做循环

C 语言中的基本循环是 for 循环,它可以实现对一组值的迭代访问。

for 基本语法:

for (初始化条件; 判断条件为真; 每次循环之后的操作) {
// do something;
}

比如,可以编写一个循环,初始化条件时设置变量 count 为 1,然后判断 count <= 10 为真时执行 {} 内的语句,在再次执行条件判断之前,对变量 count 增加 1。直到判断 count <= 10 为假就退出循环。

在每次迭代后,对变量 count 增加 1,除了常规的 count = count + 1 书写格式之外,也可以对变量采用 ++ 的自加操作符,这种变通可以使得代码更简洁易读。

在循环内部,为了直观查看变量的变化过程,可以使用标准库函数 printf 打印变量 count 的值:

for (int count = 1; count <= 10; count ++) {
printf("%d\n", count);
}

为了演示完整的逻辑,下面是一个示例程序,将数字从 1 加到 10,然后打印和的结果。

#include <stdio.h>
int main()
{
puts("adding 1 to 10 ..");
int sum = 0;
for (int count = 1; count <= 10; count ++) {
sum += count;
} printf("sum is %d\n", sum);
return 0;
}

上面的代码使用了两种函数把信息打印出来,最终输出到标准输出 stdout。puts 函数打印一个字符串,直到遇到字符串的空字符,而 printf 函数支持格式化打印,非常灵活,所以更常用。关键字 %d 表示打印一个十进制(或整数)值,\n 表示换行符。

如果编译并运行该程序,你将看到以下输出:

adding 1 to 10 ..

sum is 55

GO 语言做循环

在 GO 语言中,同样提供了 for 循环,而且与 C 语言中的 for 循环语法非常相似,甚至可以直接转换成 GO 的书写格式。

下面为了直观查看变量的变化过程,在循环内部同样使用方法打印变量 count 的值:

var count int
for count = 1; count <= 10; count ++ {
fmt.Printf("%d\n", count)
}

fmt 是包名,使用包之前需要先导入,用关键词 import。C 语言中就没有导入包的概念,只能通过包含头文件 .h 来引入其它现成模块。

fmt 实现了类似 C 语言的打印输出 printf 和读取输入 scanf。fmt.Printf 方法也是支持格式化输出的,甚至格式变量就是从 C 语言的 printf 派生而来。

在 C/C ++ 代码中,比较推荐的编码规范中通常每行是只写一句操作语句,虽然语法上多个操作语句是允许书写在同一行的,但这样易读性就很差。有没有发现,在每行 GO 语句的末尾都没有分号 ';' 了? 因为 GO 编译器默认每行就是一个语句,这样其实是强制提高了代码的可读性。

再来看看 GO 语言实现的完整逻辑,基于上面的 C 语言代码版本直接翻译如下

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("sum is %d\n", sum)
}

上面的代码是有效和可以正确运行输出的,但是这很不 GO ! GO 不单单是一门语言,也是一种态度。

有没有看到 C 语言版本中, for 循环里的初始化条件是可以同时声明定义并赋值变量的?换成在 GO 中是否也支持类似操作?

在 GO 中,有个声明变量并赋值的操作符 :=,就可以做到

for count := 1; count <= 10; count ++ {
sum = sum + count
}

另外,你如果再细心一点可能会发现,GO 代码里声明定义的变量会被默认初始化为 0,而 C 代码中定义的变量如果未经初始化会是任何未知的值,如此看来 GO 的安全性有了很大的提高。

变量的生命周期管理对开发者来说是很耗费心智的,所以很多时候变量的声明定义都是应该尽量靠近使用的地方,并且缩窄变量的生命周期,对于事故的发生可以有效缩小排查错误的范围,简直就是在打救程序员的生命啊。

再来看看,优化后的 GO 范式代码

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("sum is %d\n", sum)
}

看到这里,和 C 代码的 main 函数比起来,GO 的 main 函数没有显式的返回值。实际上,GO 的 main 函数默认返回值 0,如果需要返回其它值,可以调用 os.Exit(n) 返回值 n,这个方法可在任何位置调用,程序会在调用该方法后会终止运行并退出,就类似 C 语言中的标准库函数 exit(n) 一样。

简单回顾

从上面的逻辑实现过程来看,两种语言实现过程差别不大,语法上是有差别的,书写的习惯其实就透露着各自的态度。

虽然老气横秋的 C 语言代码很多,但是如果按照现代 C 语言书写规范来看,GO 的代码是何其相似。

虽然你会说新出来的语言有很多方便到爆炸的语法糖。但问题是,语言的精髓是语法糖吗?答案不唯一,酸甜苦辣唯有尝过的人才知道。

简单对比一下 C 与 Go 两种语言的更多相关文章

  1. 在vc6.0下编的对话框界面如果没做过其他处理,往往显的很生硬,怎么样才能使他有Windows XP的风格呢,其实也很简单,我们来看看下面两种方法。

    在vc6.0下编的对话框界面如果没做过其他处理,往往显的很生硬,怎么样才能使他有Windows XP的风格呢,其实也很简单,我们来看看下面两种方法.    方法一: 1.首先确认你在Windows   ...

  2. 《textanalytics》课程简单总结(1):两种word relations——Paradigmatic vs. Syntagmatic

    coursera上的公开课<https://www.coursera.org/course/textanalytics>系列,讲的很不错哦. 1.两种关系:Paradigmatic vs. ...

  3. 两种语言实现设计模式(C++和Java)(一:工厂模式)

    本篇开始记录实现设计模式在工作中的两种常见语言上的实现. 本篇介绍最简单的工厂模式. 工厂模式有一种非常形象的描述,建立对象的类就如一个工厂,而需要被建立的对象就是一个个产品:在工厂中加工产品,使用产 ...

  4. 使用OC和Swift两种语言写一个发射烟花的小项目

    OC与Swift两种实现方式基本上区别不大,主要是在一些对象或方法的调用方式不同,附带源码. OC代码样式: self.view.backgroundColor = [UIColor blackCol ...

  5. 两种语言实现设计模式(C++和Java)(三:策略模式)

    策略模式是指定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换.本模式使得算法可独立于使用它的客户而变化.也就是说这些算法所完成的功能一样,对外的接口一样,只是各自实现上存在差异.用策略模式 ...

  6. 识别手机浏览器代码【C#和JS两种语言】

    C# 识别手机浏览器代码: public static bool MobileBrowserDetect() { bool bismobile = false; try { #region 包含and ...

  7. C#,JavaScript两种语言 2048小游戏

    <html> <head> <style type="text/css"> .haha { border-width: 2; font-size ...

  8. 两种语言实现设计模式(C++和Java)(四:适配器模式)

    参考:http://blog.jobbole.com/109381/ 将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 系统的数 ...

  9. 两种语言实现设计模式(C++和Java)(二:单例模式)

    本篇介绍单例模式,可以说是使用场景最频繁的设计模式了.可以根据实例的生成时间,分为饿汉模式和懒汉模式 懒汉模式:饿了肯定要饥不择食.所以在单例类定义的时候就进行实例化. 饿汉模式:故名思义,不到万不得 ...

  10. C和C#两种方式实现邮件的简单发送

    内容为通过两种方式发送邮件--1.C语言发送邮件   2.C#发送邮件 一,C语言进行邮件的发送 C语言发送邮件的步骤的简单解析: 1.创建TCP连接    socket() 2.连接到邮箱服务器  ...

随机推荐

  1. 园子的商业化努力-AI人才服务:招募AI导师

    各位园子的小伙伴: 感谢大家对园子的支持,园子差不多接近20年的历程,一直是最低配模式生存和发展,感谢大家对于前段时间的困局给予了商业化的各种建议!在大家的鼓励与支持之下,园子的商业化努力正在以更快的 ...

  2. 深入理解 python 虚拟机:破解核心魔法——反序列化 pyc 文件

    深入理解 python 虚拟机:破解核心魔法--反序列化 pyc 文件 在前面的文章当中我们详细的对于 pyc 文件的结构进行了分析,pyc 文件主要有下面的四个部分组成:魔术. Bite Filed ...

  3. 如何在Docker Compose中限制容器的CPU和内存使用?

    最近我在使用开源统计Umami过程中,发现CPU和内存经常占满,导致其它服务都不能正常使用.Umami我使用的docker-compose进行部署,于是打算使用docker-compose限制下容器的 ...

  4. T-SQL——批量刷新视图

    目录 0. 背景说明 1. 查询出所有使用了指定表的视图并生成刷新语句 2. 创建存储过程批量刷新 3. 刷新全部的视图 4. 参考 shanzm--2023年5月16日 0. 背景说明 为什么要刷新 ...

  5. 自己动手写Docker学习笔记

    零.前言 本文为<自己动手写 Docker>的学习,对于各位学习 docker 的同学非常友好,非常建议买一本来学习. 书中有摘录书中的一些知识点,不过限于篇幅,没有全部摘录 (主要也是懒 ...

  6. Vulnhub Broken

    Vulnhub Broken 一.操作文档 [Vulnhub - Broken-Gallery writeup (mzfr.me)](https://blog.mzfr.me/vulnhub-writ ...

  7. 如何制作 Storybook Day 网页上的 3D 效果?

    Storybook 刚刚达到了一个重要的里程牌:7.0 版本!为了庆祝,该团队举办了他们的第一次用户大会 - Storybook Day.为了更特别,在活动页面中添加了一个视觉上令人惊叹的 3D 插图 ...

  8. 【GIS】图层中多个面要素融合成一个面要素

            对于那些利用GIS信息进行编辑,设计的GIS专业人士来说,桌面GIS占有主导地位.GIS专业人士使用标准桌面作为工具来设计,共享,管理和发布地理信息. ArcGIS Desktop是一 ...

  9. 智能合约HardHat框架环境的搭建

    1.首先创建一个npm项目 PS C:\Users\lcds\blockchainprojects> mkdir hardhatcontract PS C:\Users\lcds\blockch ...

  10. 【C++ Primer】第二章(2 ~ 6节)

    变量 变量提供一个具名的.可供程序操作的存储空间. C++中变量和对象一般可以互换使用. 变量定义(define) 定义形式:类型说明符(type specifier) + 一个或多个变量名组成的列表 ...