防止断更 请务必加首发微信:1716143665
关闭
讲堂
部落
算法训练营
Python 进阶训练营
企业服务
极客商城
客户端下载
兑换中心
渠道合作
推荐作者

01 | 学习编程,我到底该选择哪门语言?

2020-01-04 胡光
人人都能学会的编程入门课
进入课程

讲述:胡光

时长19:17大小15.46M

你好,我是胡光。欢迎来到我的极客时间专栏。在接下来的两个多月里,我将陪伴在你的每一天的清晨或是夜晚,在人潮拥挤的上班地铁上,在你家里的书桌前,再或者是在你公司楼下的咖啡厅里,每天 10 分钟,让好学的你,有所收获,就是我的任务。

那些年,我学过的编程语言

面对编程这个话题,或许你已是一位编程老手,对编程熟悉无比,现在是想查缺补漏;亦或许你是一个纯新手,对编程一无所知,学习完全是从 0 开始。不管哪种情况,在我们讨论编程学习的时候,怎么都绕不开一个话题,那就是语言选择。
鉴于以往的工作经历,我了解或者熟悉的编程语言有十几种之多,包括:
最能反映系统本质的 C 语言
叫人难以捉摸的 C++
天生就格式优美的 Python
上古级的 Pascal
神奇的函数式编程语言 JavaScript
微软系的王牌语言 C#
被誉为世界上最好语言的 PHP
使用人数最多的 Java
能够方便操作系统的 Shell 脚本语言
还有我自己开发的一门娱乐级编程语言 Hython
此外,还有一些仅仅是使用过,能看懂的语言,就不列出来了。
你可能会有疑问了,为什么我会这么多编程语言呢?原因很简单,工作中是一个边学习边工作的过程,不同编程语言擅长做的事情不一样,让专业的语言干专业的事情,这是一个程序开发人员最基本的认知,所以我能学会多种编程语言也是情理之中。
你可能又会问了,学习了这么多编程语言,难道不会造成混淆么?其实,编程语言设计者,更多的还是为了让人们使用自己的编程语言进行开发,所以语言设计本身都会有前辈语言的主流特征,这也就是为什么,只要你学习了一门主流语言后,会大大降低你学习第二门语言的成本。可第一门语言的选择,是门技术活,这也是今天我们要讲的主题。
最后你是否好奇:“我为什么还要自己开发一门娱乐级编程语言呢?”简单点儿回答就是:自娱自乐。正式点儿的回答就是:经历了开发编程语言这个过程,会对很多语言的特性理解得更深刻,知其然,知其所以然。所以当你自己能发开出一门编程语言的时候,站在开发者的角度再去学习其他编程语言,简直就属于“降维打击”般的学习。

Pascal、C、Python,哪个是你的首选?

刚才列举了十多种编程语言,接下来我会以我的亲身经历,来说说学习不同语言都有什么样的体验,以及我在学习这些语言的过程中,遇到的惊喜和踩过的坑。
我从 2006 年开始接触编程,那年,我们微机老师向我们推介一门除数学、物理、生物和化学以外的第五大学科竞赛“信息学竞赛”。我当时对计算机的印象,还停留在《热血传奇》《半条命》和《红色警戒》那个阶段,没错,我对计算机的认识都是和游戏相关。当时老师在台上介绍了一大堆东西,现在我已经忘得一干二净了。
但有件事至今我还记得:课间的时候,我问老师:老师,编程学好了,能做游戏么?老师说了一声:恩!就是那种不置可否的“恩”,可以自行脑部相声演员岳云鹏的那个"恩"。对于幼小的我来说,这就是肯定句,从此我就踏上了学习编程的道路。
我所接触的第一门编程语言是 Pascal,这是一门上古级的编程语言,语法风格类似现在的 Python 和 C 的混搭风。现在没有多少人使用的原因,我猜是因为其特立独行的语法规则。Pascal 程序需要你在最开始把所有需要的变量都定义一个遍,然后再描述程序的过程逻辑。所以当时我们打趣说,作为 Pascal 的忠实用户,我们比那些使用 C 语言的要思虑周全。
下面放一段 Pascal 的“判断素数”的程序,你自己感受一下这门上古级语言那遮挡不住的力量。这段代码你看不懂没关系,只是让你对 Pascal 有个直观的感受。
program JudgePrime; // 程序名称
var x, i : integer; f : boolean; // 变量仅能在此定义
begin
readln(x);
f := true;
if x < 2 then
begin
write('F');
exit;
end;
for i:=2 to trunc(sqrt(x)) do
if x mod i=0 then f:=false;
if f then write('T') else write('F');
end.
在这段用 Pascal 写的判断素数的程序中,第一行是程序的名字,第二行就是定义变量部分,并且变量只能在这里定义。从 begin 到 end. 中间就是我们所谓的程序逻辑部分了,是不是有种看 Python 代码的感觉?
你能想象么,那时稚嫩的我,在定义变量名这件事儿上,把 26 个英文字母都用遍了以后,最后不得不使用类似 “aa”“bb”“ccd” 这种变量名,往事不堪回首啊。
过了两年,为了参加 ACM 竞赛,不得不学习 C++ 了,准确地说,是学习 C 语言风格的 C++,就像印度人说英语,怎么说怎么一股咖喱味儿。因此,在转 C 语言之前,我还有点儿担心这个过程会比较坎坷,谁知道,就用了几天的时间,就搞定了我编程时候需要的几乎全部语法。你要知道,我学习 Pascal 的时候,可是花了四个月啊!
从这以后,我才意识到那句话的真正含义,那句话是这样说的:“语言从来不是编程的障碍,思维才是”。所谓“思维”大多数的时候,反映出来的是“编程技巧”,更形式化一点,我们叫它 “编程范式” 和 “算法数据结构”,这部分的东西,我后面还会着重讲解,并且会教你一些提升编程技巧方法。
当时的 C 语言,真是一上来就让我欲罢不能。下面我给你来一段判断素数的 C 语言程序,你来感受一下,就像感受一个刚从牢笼中挣脱出来的鸟,正如汪峰有首歌所唱的:这是自由的感觉!
#include <stdio.h>
int main() {
int x; // 定义变量 x
scanf("%d", &x);
int f = 0; // 定义变量 f
for (int i = 2; i * i <= x; i++) { // 定义循环变量 i
if (x % i) continue;
f = 1;
break;
}
if (f) printf("F\n");
else printf("T");
return 0;
}
和上面的那段 Pascal 程序对比,你发现差别了么?对!就是变量定义这里,C 语言中我想在哪里定义,就在哪里定义!从此我跟 C 语言进入了蜜月期。
C 语言除了可以随处定义变量这个特性,它与 Pascal 语言还有什么不同的特性呢?这里就不得不提到我曾经做数独程序的经历了。有一次我在做一个数独的题目,就是每行、每列和每个 3*3 的宫格内部,不重复地填上 1~9 这 9 个数字。
这个问题我曾经用 Pascal 语言做过,解题思路是:每次向函数中传入一个代表数独的数组作为参数,然后不断尝试修改这个数组中相应位置的值,如果尝试进行不下去了,就回到上一个状态,重新尝试。
我就原封不动地将 Pascal 语言的解题思路搬到了 C 语言中,但怎么调试都是错的,我自己反反复复检查逻辑,可就是查不出错误。在挣扎了一下午以后,我终于忍不住,求助了学长,这才发现,有一个关键的语言特性,C 语言和 Pascal 完全不一样。下面我就说说这个事儿,你现在听不懂没关系,希望你记住这个事情,等到我们一起学习了一段时间以后,你再回头来细看这段。
普通变量向函数中传值,就是将原变量中的值拷贝给函数参数的过程,这个过程,我们称作“实参给形参赋值”。原变量就是实参,函数参数就是形参。在这个过程中,本质上还是两个变量,两片独立的存储位置,也就意味着,我们对形参的改动,不会影响实参。这一点上,C 语言和 Pascal 是完全一致的,下面就要说到不太一样的地方了。
请观察图 1,在 Pascal 中,如果你将一个数组作为参数传递给一个函数,函数内部还是会复制一份这个数组,也就是说,在 Pascal 中数组的传递过程和普通变量的传递过程没有任何区别。
你再观察图 2,图 2 展示的是 C 语言中数组作为参数传递的方式,你在图中会看到一个 “0x1234” 的信息,我们称之为地址,就类似于你家的门牌号。当我们传递一个数组时,其实在传递的是数组的首地址,也就是说,无论实参还是形参,实际上指向同一片存储区!
总结来说,对于数组,Pascal 函数内外,是两个互不相同,互不影响的存储区。C 语言则是函数内外是同一片存储区,任何一个修改,都意味着外部的数组也被修改了。就是这点差异,导致我用一下午也没找到错误的原因!
看了上面这段,不知道你可不可以理解我当时的困扰。我当时用 Pascal 的语言特性去检查 C 语言的程序,从逻辑上来讲,当然是发现不了任何 Bug 了。当时我还以为这个语言特性,是 C 的特立独行,后来才发现,特立独行的是 Pascal。
从我的这段经历你可以发现,初学编程选择什么语言作为自己的第一门语言是多么重要。如果你选择一个比较“偏”的语言,形成了它独特的语言特性,可能会对你学习其他语言造成不小的困扰。而 C 语言,由于它的共通性,很少会出现这样的问题。
最后给你介绍的一门语言就是 Python,上面我们欣赏过了从 Pascal 过渡到 C 语言的神清气爽,那你知道如果你学完 C,再学 Python,是什么感觉么?简直就跟吃了一大口芥末一样,提神!下面来看看 Python 的判断素数的一个程序。
#!/usr/bin/env python
# coding=utf-8
x = int(input())
i = 2
while i * i <= x:
if x % i == 0:
print("F")
break
i = i + 1
else:
print("T")
对比上面的两段代码, Python 的这份代码,是不是看着就简洁、清爽?而 Python 为什么被评价为天生就格式优美呢?那是因为,在 Python 中,如果你不按照缩进组织程序的层次关系,你的程序根本没有办法正常运行。
不同的人编写代码可能有不同的风格,就像 C 语言,10 个人可能就有 10 种风格,但 Python 的代码风格就像人的指纹,它是天生的,不管多少人用 Python 编写代码,可能也只有一种风格。所以无论你是否写过程序,在写 Python 的时候,都将写得很漂亮,很舒服。
最适合学习编程的操作系统是 Linux,Linux 中有一个核心设计思想,叫做“一切皆文件”,理解了文件,就理解了整个 Linux 操作系统,这里说的文件,可不是你所认为的常规的 windows 文件。Linux 世界中的文件,就像是我们这个世界中的原子一样,是一种本质。
而 Python 中也有一个类似的核心设计思想,就是“一切皆对象”,理解了什么是对象,你就理解了 Python。而这么抽象的概念,我不认为我现在可以用两三句话就给你讲明白,不过还是那个道理“语言从来不是编程的障碍”,关于对象这个概念,在你日后对编程的知识逐渐丰富起来以后,自然就会明白了。

编程入门,舍我其谁:C 语言

听完了以上三种语言的介绍,你可能已经打定主意准备把界面精练的 Python 作为自己学习编程的入门语言。但是如果看完下面我给你的这张图,你可能需要再考虑考虑。
上图中的时间,只是一个参考,可能你比较有天赋,会比图中所标记时间用时短,可绝大多数的人,只会多于图上的时间,不会更少的。你会看到图上有两条学习路径,绿色的学习路径用时两个月多一点,红色的学习路径用时四个月。其实这张图,我就是想跟你说明,在我们学习过程中的一个重要的概念:学习路径。一个合理的学习路径,可以帮助你大大缩短整体的学习时长,毕竟你的时间才是最大的成本。
其实正如你所看到的,你用相同的时间掌握了 C 语言后,会对你学习其他语言有很大的帮助。反观,如果你一上来掌握的就是拥有很多奇怪语法特性的语言,不仅要花很长时间学,在日后的学习中,你会发现这些语法特性在其他语言甚至都找不到。基于这类知识锻炼出来的编程思维,是不具备延展性的。所以,在选择第一门语言的时候,一定要选择简洁、高效、不拘泥于语法特性的语言。就像学习武功一样,摒弃掉花拳绣腿,去稳扎稳打的进行练习,才是快速成长的诀窍。
这里,请记住:学习编程不等于学习语言,前者包含后者,也就是说想学好编程,不仅是学好语言,还有很多比语言更难的东西等着你呢。
既然要给你讲编程,我决定选择一门既可以带你潜入底层系统一窥究竟,又可以顺畅简洁表达逻辑,还没有特别多奇奇怪怪的语法特性的语言。我希望借助这门语言,让你在学习编程的过程中,能够专注于编程思维训练本身,帮助你一步一个脚印地学习编程,培养编程思维。这门语言,就是我们前文说到的 C 语言。
我有朋友是这样形容 C 语言的,我觉得很贴切,拿过来用一下,他说:学编程就像是学乾坤大挪移,而 C 就是语言中的九阳神功。

推荐书籍

专栏里面呢,由于篇幅有限,没有办法穷尽 C 语言的所有知识。不过,我讲的会是一些容易被你忽视的,容易被你误解的,以及你自学不容易学会的知识点。而关于 C 语言更多的知识,我专门买了市面上最畅销的 15 本 C 语言的书籍,经过一番筛选之后,我选出来了以下三本小册子,推荐给你。之所以说是小册子,那是因为他们每一本较其他 C 语言的相关书籍都很薄,内容也很详实准确,并且在内容上,三本有着递进的关系。
第一本:《啊哈 C 语言》
这本由电子工业出版社出版的《啊哈 C 语言!》被叫做“厕所 C 语言教科书”。这不是在说这本书很差,恰恰相反,这是一本浅显易懂的 C 语言入门书籍,即使是利用蹲马桶的时间看上一会儿,你也是看得懂的。并且和书籍配套的还有《啊哈 C 语言!》特别版编译器,会使得你在学习 C 语言基础知识的时候,更加轻松,自在。
第二本:《C 专家编程》
这本由人民邮电出版社出版的《C 专家编程》,会是你入门 C 语言以后的第二本必备书籍。这本书,会从 C 语言的发展历史讲解 C 语言中一些语法特性,以及相关语言特性当初被设计的目的,以及现有的缺陷,会给你一个更深层次的解释。并且,作者给你展现的,不仅仅是教你 C 语言语法,更多的是在给你讲 C 语言是怎么被设计出来的。这会使得你对于你今后所写的每一行代码,都会理解得比旁人深刻。
第三本:《C 缺陷与陷阱》
这本也是由人民邮电出版社出版,可以说是《C 专家编程》的延续,针对性会更强,直接指出 C 语言中各种各样的问题,并且加以分析。正所谓人无完人,那么由人所设计出来的语言,当然也没有完美的。你作为外行的时候, C 语言的美足够好好体会和欣赏,可想成为内行,你就必须要知道你所使用的工具,有什么缺点和短板,这样才能真正的在日后应用中,游刃有余。

课程小结

说了这么多,今天我只是想让你记住一件事情,不同的学习路径,会有不同的时间成本。C 语言只是我们入门编程的一个载体,也是最有效、最深刻的一个载体。从 C 语言入手,会使得你的总时间成本最低。永远记住,扎扎实实,稳扎稳打,才是真正的捷径。
最后呢,请你想一想,在你的学习过程中,有没有哪块知识,是你身边的行业前辈们告诉你很重要的,你一开始忽视了,然后过了好久,才发现,前辈说的对的,欢迎留言给我。
我是胡光,今天我们就先聊到这儿,下期内容,我们不见不散。
我录制了一个关于编程环境说明的视频,如果有对编程一点也不熟悉的朋友,可以看看这个视频,了解一下编程环境。
00:00 / 08:48
unpreview
© 加微信:642945106 发送“赠送”领取赠送精品课程 发数字“2”获取众筹列表。
上一篇
开篇词 | 别闹了,学编程 ≠ 学语言
下一篇
02 | 第一个程序:教你输出彩色的文字
 写留言

1716143665 拼课微信(24)

  • 2020-01-04
    老师,你好能不能介绍一下,您从市面上买的15本C语言编程书籍都有哪些?

    作者回复: 1.《C 语言核心技术》-->简称牛书
    2.《C 语言入门经典-第5版》很经典,但不推荐新手看
    3.《C 语言从入门到项目实战》这本书的项目讲得很好
    4.《C Prime Plus 第6版》
    5.《零基础入门学习 C 语言》
    6.《『笨方法』学 C 语言》
    7.《第一行代码 C 语言》计蒜客联合出品的
    8.《啊哈 C 语言!》
    9.《C 陷阱与缺陷》
    10.《C 专家编程》
    11.《C 程序设计 第五版》
    12.《C 语言从入门到精通》
    13.《算法:C 语言实现》
    14.《零基础:学 C 语言》
    15.《C和指针》

    纯手打,亲给个好评哈。

    PS:建议留言回复加个图片功能 -_-|||。

    2
    30
  • for (int i = 2; i * i <= x; i++) { // 定义循环变量 i
            if (x % i) continue;
            f = 1;
            break;
        }
       ———————————————————
    老师好,如果是纯正的C语言,for循环里面不能直接定义变量,但是老师是在C++环境(文件名是cpp)下,所以这个能运行。而老师的背景是在纯C的背景下,那么这个语法就是有问题的。C语言的变量都是先定义后使用。
    个人愚拙,如果说得不对,还请老师见谅!
    展开

    作者回复: 你这个问题非常好,也可能是大多数同学的问题。C语言for循环里面不能定义变量,这个已经是上个世纪的事情了,自从C99标准以后,C语言的循环中是可以定义变量的。

    1
    10
  • 2020-01-04
    《啊哈 C 语言》编辑器可以到 https://www.ahacpp.com/ 下载,书中的下载链接已失效,是个菠菜网站。

    作者回复: d(^_^o)

    1
    6
  • 2020-01-04
    老师,看你文章举例,函数式编程语言最佳代表是JavaScript吗?

    作者回复: 如果说最具代表性的,个人认为还是:Lisp语言。可很多其他语言也支持函数式编程范式,例如:你所说的js,还有Python以及C++11以后的lambda表达式等等。都是为了支持函数式编程。

    4
  • 2020-01-04
    我也认为c语言最适合入门的语言,不过现在市面都充斥着大量的python语言的教程。我是大一上学期学的c语言,当时啥也不懂,只知道老师说他是面向过程的,不过面向过程又是啥啊,还是不清楚,老师只好说,以后学了面向对象就知道了。大一下学期又学了java,才慢慢体会了语言之间的互通,语法其实都是相似的。那么学了c语言之后对于学java有什么真正有用的体会呢。我觉得吧,刚开始学面向对象的时候,会对对象这个东西感到有点陌生,甚至捉摸不透,怎么一下子new出来,就可以直接用了。直到我有一个老师说,只要对应c语言里面的内存分配malloc函数,就好理解了。后来我又回头学了一下关于内存分配的内容,就有那个味道了,也容易理解了。当然,后来又了解了些jvm的底层知识,就更理解透彻了,这是后话了。
    展开

    作者回复: d(^_^o)

    4
  • 2020-01-06
    老师,我觉得activefeng同学的对于代码的优化的观点是有道理的。
    从老师的代码逻辑看:
    if (f) prinf("F\n") -- 非素数,f=1, 打印F
    else printf("T") -- 素数, f=0, ,打印T
    需要读者在脑海中转化一遍并从上文的f的逻辑中判断才能理解其代表的含义,我也觉得不是很好,我的观点是代码最好是明了,从阅读上就能很快意识到一些变量代表的含义,而不是需要读者再去思考和跟代码逻辑。
    请老师指点。
     
    展开

    作者回复: 你们说的都没错。d(^_^o)这个问题不是二选一的问题,而是各种代码,你们都需要掌握的事情。毕竟以后,你们不是在看自己的代码,而是要大量阅读别人的代码。每个人的编码习惯反映的是思维习惯,所以,你们说的没错,还要兼容并包的去看待代码设计问题,注意,这不是一个拥有标准答案的问题。

    2
  • 2020-01-06
    C语言是大学期间学习的第一门语言,当时觉得其语法简单,较易上手,能理解计算机运行原理,同时陷阱又多,很容易遇坑。希望老师能在第一部分多讲解点语言的重要的知识,毕竟是基础不牢,地动山摇。

    作者回复: 我会讲一些容易被大家忽视和学错的东西。还有哪些点没有照顾到的,咱们可以在留言去讨论。我可以在留言区回复大家。Y(^_^)Y

    2
  • 2020-01-04
    小白到第二节看到代码已经晕了
    展开

    作者回复: 没关系,先别怕,可以配合我推荐的第一本书籍,配合学习,对于初学者来讲,效果会更佳。^_^

    1
    2
  • 2020-01-04
    哈哈,我是来学习C语言的,就大学为了考计算机等级学了一段时间,后来就没有再用过了

    作者回复: (。ì _ í。)

    2
  • 2020-01-07
    老师,你用什么软件画图的?
    展开

    作者回复: Mac下面的 keynote

    1
  • 2020-01-07
    胡老师,为什么演示安装环境是未激活版的windows?
    展开

    作者回复: ⁄(⁄ ⁄ ⁄ω⁄ ⁄ ⁄)⁄新安装的,激活码还没有使用,囧。

    1
  • 2020-01-07
    老师,c prime plus为何不推荐呢
    展开

    作者回复: 是这样的,不是不推荐,而是不满足我的推荐标准。你们可以自己买,当成工具书看。我推荐的标准是:薄,内容有效,达到相同效果,花费的时间更少。(。ì _ í。)

    1
  • 2020-01-06
    谢谢老师一直耐心的解答:Windows,编译运行,黑框一闪就不见了的问题。
    最后发现是devcpp版本问题,重新下了一个就没问题了

    作者回复: d(^_^o)

    1
  • 2020-01-06
    从《啊哈C语言!》直接到《C专家编程》感觉跨度太大了,中间用《C和指针》过渡一下会比较好

    作者回复: 可以的,d(^_^o)

    1
  • 2020-01-04
    朋友给我DEVCPP安装包,然后我解压安装就好了,按照作者大大视频里的操作木问题:D

    作者回复: d(^_^o)

    1
  • 2020-01-04
    打算今年考软考,有Python语言基础。学完老师的专栏,还需要看c的书籍吗?

    作者回复: 当然是需要的,专栏篇幅有限,我会尽可能的把你们自学过程中会忽略的,会误解的知识点讲给你们,而不是全部的C语言知识。

    1
  • 2020-01-04
    老师,您视频中vim是不是装了一些插件?感觉那个提示当前光标在哪一行的插件不错,能分享下吗?

    作者回复: ma6174

    1
  • 2020-01-04
    老师我认为c语言素数算法应该简化为:
    int f = 0;
    for (int i = 2; i * i <= x; i++) {
            if (x % i == 0) break;
            f = 1;
    }
    if (f) printf("F\n");
    else printf("T");
    展开

    作者回复: 专栏里面的代码如果要是说到简化的话,有很大的简化空间,可我没办法马力全开,只能点到为止,所以在专栏里面,我尽量的不去提短码之美的内容。⁄(⁄ ⁄ ⁄ω⁄ ⁄ ⁄)⁄

    1
  • 2020-01-04
    现在想来,当年就是被一些粗制滥造的书误导了,以前都说VB简单,就买了一本书,上面全是教你怎么复制API的,看的我云里雾里,现在跟着老师的课程,有了一个契机,放下过去,重学编程。

    作者回复: (。ì _ í。)如果是基础薄弱的话,注意配合推荐书籍进行学习,效果更佳哦。

    1
  • 2020-01-04
    大佬很有趣!文章写的很好!
    展开

    作者回复: (*^o^*)

    1