You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

177 lines
17 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 01 | 学习编程,我到底该选择哪门语言?
你好我是胡光。欢迎来到我的极客时间专栏。在接下来的两个多月里我将陪伴在你的每一天的清晨或是夜晚在人潮拥挤的上班地铁上在你家里的书桌前再或者是在你公司楼下的咖啡厅里每天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的宫格内部不重复地填上19这9个数字。
这个问题我曾经用 Pascal 语言做过,解题思路是:每次向函数中传入一个代表数独的数组作为参数,然后不断尝试修改这个数组中相应位置的值,如果尝试进行不下去了,就回到上一个状态,重新尝试。
我就原封不动地将 Pascal 语言的解题思路搬到了 C 语言中但怎么调试都是错的我自己反反复复检查逻辑可就是查不出错误。在挣扎了一下午以后我终于忍不住求助了学长这才发现有一个关键的语言特性C 语言和 Pascal 完全不一样。下面我就说说这个事儿,你现在听不懂没关系,希望你记住这个事情,等到我们一起学习了一段时间以后,你再回头来细看这段。
普通变量向函数中传值就是将原变量中的值拷贝给函数参数的过程这个过程我们称作“实参给形参赋值”。原变量就是实参函数参数就是形参。在这个过程中本质上还是两个变量两片独立的存储位置也就意味着我们对形参的改动不会影响实参。这一点上C 语言和 Pascal 是完全一致的,下面就要说到不太一样的地方了。
![](https://static001.geekbang.org/resource/image/33/65/33a9733f80d76da885c16b1bcb09e165.jpg)
请观察图1在 Pascal 中,如果你将一个数组作为参数传递给一个函数,函数内部还是会复制一份这个数组,也就是说,在 Pascal 中数组的传递过程和普通变量的传递过程没有任何区别。
![](https://static001.geekbang.org/resource/image/e9/56/e9a796386b27d4b3eb76b65194b37356.jpg)
你再观察图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 的时候,都将写得很漂亮,很舒服。
最适合学习编程的操作系统是 LinuxLinux 中有一个核心设计思想,叫做“一切皆文件”,理解了文件,就理解了整个 Linux 操作系统,这里说的文件,可不是你所认为的常规的 windows文件。Linux 世界中的文件,就像是我们这个世界中的原子一样,是一种本质。
而 Python 中也有一个类似的核心设计思想,就是“一切皆对象”,理解了什么是对象,你就理解了 Python。而这么抽象的概念我不认为我现在可以用两三句话就给你讲明白不过还是那个道理“语言从来不是编程的障碍”关于对象这个概念在你日后对编程的知识逐渐丰富起来以后自然就会明白了。
## 编程入门舍我其谁C 语言
听完了以上三种语言的介绍,你可能已经打定主意准备把界面精练的 Python 作为自己学习编程的入门语言。但是如果看完下面我给你的这张图,你可能需要再考虑考虑。
![](https://static001.geekbang.org/resource/image/27/ad/27b55e38da2f15736e4f226a692395ad.jpg)
上图中的时间,只是一个参考,可能你比较有天赋,会比图中所标记时间用时短,可绝大多数的人,只会多于图上的时间,不会更少的。你会看到图上有两条学习路径,绿色的学习路径用时两个月多一点,红色的学习路径用时四个月。其实这张图,我就是想跟你说明,在我们学习过程中的一个重要的概念:学习路径。一个合理的学习路径,可以帮助你大大缩短整体的学习时长,毕竟你的时间才是最大的成本。
其实正如你所看到的,你用相同的时间掌握了 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 语言入手,会使得你的总时间成本最低。永远记住,扎扎实实,稳扎稳打,才是真正的捷径。
最后呢,请你想一想,在你的学习过程中,有没有哪块知识,是你身边的行业前辈们告诉你很重要的,你一开始忽视了,然后过了好久,才发现,前辈说的对的,欢迎留言给我。
我是胡光,今天我们就先聊到这儿,下期内容,我们不见不散。
> 我录制了一个关于编程环境说明的视频,如果有对编程一点也不熟悉的朋友,可以看看这个视频,了解一下编程环境。