课程介绍

欢迎大家来到计算机科学与技术导论课程,我是你们的学长xxx,对与你们来说,这是第一次迈入大学校园,心情是五味杂陈的,同时怀有着不安与兴奋,但我看到更多的是大家从高中毕业之后那种迷茫。迷茫着自己的将来,尤其是眼下的大学四年该学些什么。 所以这门课就诞生了,非常感谢我们的长老对我的大力支持以及我的朋友们对整个课程项目的鼎力相助,没有他们这门课也就无从谈起。 同时也要感谢以下几门公开课:

  1. 哈佛大学 CS50 —— 课程的内容
  2. 麻省理工 missing semester —— 课程的“哲学”
  3. 南京大学 ics —— 课程的文档
  4. 南京大学 OS —— 课程的上课形式

很荣幸这门课能成为大家的第一门专业课,而我在接下来的一个学期里将带领大家认识我们整个计算机科学与技术专业的冰山一角,也就是“什么是计算机?”,而在上课的过程中通过我的介绍会引导大家养成一套正确的学习计算机的方法 这门课的目标是:

  1. 让大家在大二的时候能够具备上 NJU ics 和 NJU os 的水平
  2. 计算机真的很好玩
  3. ???

为什么要学计算机?

拿高中数学书上的导言作为例子 image.png 但更重要的是:计算机是好玩的!而且很酷! 【介绍lab】

什么是计算机科学

言简意赅地说,就是问题求解。举个例子:大家都用过计算器对吧,我们有一个式子通过输入计算器,计算器就能返回给我们一个正确的结果。如何解决呢?这听起来有些不知从何下手,但是计算机科学有一个重要的特性就是分层,如果我们把上面的这个例子要求更明确地表示出来大概就如下所示: image.png 这个时候,我们拥有的工具就是编程语言(相当于拥有了数的表示,加减乘除的基本运算),我们所要做的就是识别出数字和运算符号,决定运算顺序。 我们可以将所有的问题求解抽象为下面这个图:我们有一个输入,我们有一个期望输出,中间这个过程就是问题求解的过程。 input->problemsolving->output 比如说,我的输入可以是一段图片,输出是图片右上角加了一个水印(ffmpeg)

ffmpeg -i count.mp4 -i PopUp.png -filter_complex “overlay=W-w-5:5” -codec:a copy output.mp4

输入可以是一首歌,输出是人声和背景音乐的分离(https://github.com/Anjok07/ultimatevocalremovergui),输入可以是一种语言,输出是另一种语言(翻译)。

数据的表示

既然我们要对图片,文本,音乐等进行操作,那么我们需要事先决定我们如何表示这些输入和输出。

数字的表示

在计算机的世界中,一切都是二进制的。这意味着我们只能用若干个1和若干个0去表示这个世界,但是这个世界显然不仅仅只有0和1,我们可以在电脑上打游戏,可以看视频,通过聊天软件给远方的家人们通信,那我们是怎么只通过一些0和1去实现今天的这一切的呢? 如果我要点一下现在在这个教室里的人数,我可以用我写正字,这样的表示方法成为“一进制”,这意味着如果要表示一个自然数 n 次,我只需要画 n 条直线就可以了。由于这种表示方法简单直观,是最早被人类发现使用的。如果我们的人数再多一点,可以直接用阿拉伯数字写下到场的人数。 那么计算机中的这些0和1是如何来数数的呢? 例如,在二进制中,这将是0。

0 0 0

而这将是1。

0 0 1

由于没有2的数字,我们需要改变另一个数字来表示下一个数字。

0 1 0

然后我们要 “加1 “来表示3。

0 1 1

然后继续用这个模式表示4……。

1 0 0

… 5 …:

1 0 1

… 6 …:

1 1 0

…和7

1 1 1

每个二进制数字也被称为一个比特。 由于计算机是靠电力运行的,而电力可以被打开或关闭,我们可以简单地通过打开或关闭一些开关来表示一个比特,以表示0或1。 在现代计算机内部,有数十亿个被称为晶体管的微小开关,它们可以被打开和关闭以代表不同的值。
而用多比特的二进制进行计数的模式与用多位数的十进制进行计数的模式是一样的。
例如,我们知道下面这个数字在十进制中代表一百二十三。
大多数计算机每次使用8位,称为一个字节,如0000000011代表数字3。

文本的表示

既然我们已经能表示数字了,那么直接建立一个数字到字符的映射不就可以表示文本了?你真是个天才!你和美国国家标准学会想的一样。直接用 97 代表 a,然后以此类推,总共能表示 95 个可显示字符和 33 个控制字符。但是这种表示方法有什么缺点呢? 除此之外还有一个疑惑:为啥 97 是表示字符 a?为啥不是 31 表示 a?所以到这里你会发现计算机科学的第二个特点:人为约定。

比如 97 既可以表示 97 这个数,也能表示字符 a,其实这是一件很浪漫的事情,你完全可以设计你的一套 ASCII,然后你就拥有了整个世界。

Unicode

想要表示更多字符?加位数!UTF-32——直接加到32位!UTF-8动态调整字符需要的位数。甚至把emoji也包括在内了。

多媒体的表示

  1. 图片——像素点 RGB,手写图片!
  2. 视频——连续的图片,再加点声音
  3. 音乐——MIDI,mp3,wav

进入计算机的世界!

我们这门课程的前半部分是用c语言来教大家如何了解整个计算机世界的基础的,这门语言就相当与计算机大厦一楼的承重墙,非常接近计算机底层实现并为上层提供基础。 平时我们无论是使用手机还是电脑,在手机上我们点击一个应用的图标,就能弹出一个窗口,在电脑上双击一个图标,也能有对应的现象。和图片,视频一样,它们都能被我们以文件的形式删除,丢进回收站,那么这些点击能产生对应现象的程序是不是也是若干个0和1呢?没错! 还记得我们的第二特点吗?人为约定!为了了解程序是如何运行的,我们可以自己来想个程序运行的定义! 我们可以人为约定,一个10个字节的程序其中一半是数据区域,一半是逻辑区域,我们运行一个程序,就是从逻辑区域每次取一个字节,然后根据下面这个表做出相应的动作:

| 操作类型 | 数字一 | 数字二 | |—|—|—| :logbook: CLOCK: [2022-07-25 Mon 16:56:19] :END: 例如我们规定:

  1. 0001 操作类型将 数据区数字一位置 复制到 数据区数字二位置
  2. 0002 操作类型将 数据区数字一位置 等于 数字二
  3. …..
    还记得我们的第一特点吗?分层!所以这个规定我们其实是由CPU提供并且执行,这样一套的操作集合被成为指令集(ISA) 你可能听说过 x86 arm 之类的 cpu 架构之分,它们最大的不同就是指令集的不同,至于如何去用电路实现指令集承诺的功能,那就是CPU的事情了!

为了证明->查x86手册 展示 counter hack image.png 理论上你确实可以只用这样的键盘就能写出世界上任意一个程序,不过在座的各位大部分应该不是硅基生命所以我不建议大家这么做。 所以我们有了一门语言叫做汇编,汇编就是引入一些特殊的记号,然后让人更方便书写程序。汇编会通过汇编器经过一段相对简单的过程,变成若干个0和1 8086模拟器 但是汇编也有很多问题,比如说比较费程序员,换一个机器就要重新写代码。 于是我们的前辈们就想:能不能开发种语言,将这种语言写的代码通过一段程序变成汇编,然后就能用前辈的前辈们实现的汇编器,变成能被计算机识别的01序列了! c语言就是那个时代的一员。 发明c语言的人肯定是最懂c语言的人之一,假设我们穿越回1972年,Dennis Ritchie 正好在开设补习班教大家c语言,除了语言不同之外,在那里学c语言和我们现在学c语言有什么区别呢? 最大的区别就是,当时没有windows,没有macos,第一款商业鼠标要9年后才出现,你大概会在用DOS的操作系统,如今我们可以使用Linux来获得相近的体验。 区别于我们今天看到的拥有图形化用户界面(Graphical user interface )的系统,当时的系统只有CLI(command-line interface),也就是命令行界面。
image.png 虽然如今我们有着各种各样的工具来帮助我们使用计算机,但是在计算机学习的过程中我推荐大家尽可能地使用CLI,理由有以下几点:

  1. 使用CLI来操作计算机本身就是编程
  2. 能够很方便与现有工具结合使用
  3. 如果你知道命令,CLI可以比任何其他类型的界面快得多,效率也高。它还可以轻松处理重复性任务。
  4. 世界上很多计算机是没有图形界面的,而大多数人工作后都要接触它们。

当然这不是禁止大家使用GUI,事实上,如何正确地将两者结合起来也是这门课要教会大家的一点。在这周的环境配置上,大家就能体会到。 好了,接下来就真正进入到我们的第一个c程序!

  int main(){
    return 0;
  }

欸?就没了?这不是什么都没做吗?没错,但是这就是一段最简单的c程序代码,这里的 main 是函数名,就像数学的函数 f(x)=x 中的f一样,前面的 int 代表它返回的是一个整数,大括号里是函数体,这里我们固定返回0 c语言约定一个c程序是从 main 函数开始的,返回一个整数。

为什么是返回0?
这是因为我们的操作系统对一个程序有无正常执行完毕是通过程序的返回值来判断的,正常执行完毕就是0

为了将这段代码转换成能够运行的程序,我们就要做之前提到的那些步骤,把c代码变成汇编代码,再将汇编变成0和1,而这些步骤前人都帮我们写好了工具,我们只要会使用就可以。