@bintou
2020-10-24T21:18:51.000000Z
字数 3602
阅读 2080
图灵班
教学手记
一个学生自发组织的学习小组。
阅读ThinkC(这是指南),学习编程。请到课堂派上提交代码(加课码:ZCQP23)。请让我看到你的信心、决心与执行力。
首先同学们需要自愿提交一份申请,然后根据课堂派或者平时的表现,加一个简单的面试来决定。国庆后就开展此项工作。
现在要求大家具备以下技能:
- 翻墙,使用Google(远离Baidu);
- 懂得使用GitHub分享、阅读代码;
- 懂得双系统安装,linux系统使用;
- 使用MarkDown写作、分享代码(推荐这个)、分享知识;
- 坚定阅读英文教材的决心(为什么要看英文教材?)。
今天17级某师兄义务为新生讲了一次课(这是讲义),其中讲到了函数。关于函数,我补充如下。
可能到了课堂上,一个月都不会讲到函数,但是今天第一节课就讲了,是不是冒进?首先,学编程不仅仅是学语法,是学处理问题的方法。其次,函数就是思考问题的第一步。比如,写个程序目的一定是要解决问题,什么是问题?立即就想到输入什么,输出结果是什么。这就是函数定义了。注意,具体怎么实现是下一步,请大家写程序的开始就考虑输入输出。接下来才考虑输入输出的数据类型或数据结构。再才是处理问题的算法。所以,回应第一天给大家说的,什么是程序?数据结构加算法。如果现在入门的时候不强调,就很有可能出现高年级同学写程序只有main函数的坏习惯。main函数只是一个控制函数,主要用于与用户的交互,请区分处理问题与人机交互的不同。这是我非常想补充的一点,具体的一些想法大家可以看这一份关于算法思维训练的讲义。
关于用什么语言教编程,这个很有些故事的。很早大家就发现了C语言不适合入门,某些欧美高校就用函数式语言进行教学,有一本很著名的教材How to design programs(HTDP)。而SICP更是其中佼佼者,使用Lisp和Scheme教程序。SICP是我看过最牛的教程序设计的教材。
但是,似乎全世界都没有往这更合理更高级的方向发展。最早使用SICP的MIT也是对函数式语言发起攻击的最早的一波高校之一,然后提出SICP-Python版本。结果当然是也没有很流行,就我个人来看,SICP-Python是失败的。
人类的发展怎么会倒退着走呢?其实,倒退着走基本是必然的。打个比方,你说开兰博基尼、保时捷不比开奥拓好吗?但是,如果你的大环境就是脏乱差,奥拓还是挺适合的。现在的计算机系统环境有多好?估计还是属于脏乱差之列吧。C语言香还是Go香?当然,Go香。但是计算机系统的母语是C语言啊,就好比你问象形文字好还是拉丁文字好?就算象形文字再不科学,作为你的母语还是得学的,对吧?如果明白到这个道理,那就要学C的。只是,不要太认真太努力学,应该把它视为一种入门工具、一种描述问题的朴素语言。(类似的,学了中文还是要学英语的。)以此为基础,尽快走向更高级的语言,则进可攻、退可守。没人让你一辈子抱着C不学新语言不是吗?所以,C语言还是挺香的!
可能大部分同学没有理解为什么要提交代码,当然是接受批评了。否则怎么进步呢?也许我批评的这句“fibo函数输入什么、输出什么?大家理解这里的输入是不是一定要键盘输入scanf?输出就一定是屏幕输出printf?面向问题去思考。”大家也没有明白。因为也没人问啊。我再继续啰嗦几句。请问,你写了这个Fibo函数给谁用?怎么用?比如,我把问题扩展一下,请尝试不同的整数n,求第n项斐波那契数与第n+1项斐波那契数的比值,并问当n趋向很大的时候,这个比值是否会接近某个数值?好,你开始做这题,于是就发现,咦,之前写的Fibo竟然帮不上忙,需要重新修改。所以,小结一下,如果某同学写的Fibo函数能继续在新问题下使用,恭喜你,你有非常好的思维习惯。
我点评的那段代码大概长这样。
int Fibo()
{
scanf()
......
printf()
}
看上去这个问题似乎无伤大雅。让我想起在大二作业当中看到的,当我要求大家写函数求,有同学在函数中scanf
这个n,让人啼笑皆非。为什么出现这样的问题?无非入门的时候从来没有人提醒罢了。希望这些唠叨能起一点作用。
有几位同学反映最近一直在看书,没写代码,就没交作业。是这样的,学程序设计,看书的同时一定要动手,一定要动手,一定要动手!这是专业性决定的。动手写代码是必须的。建议大家就是看书1小时,就赶紧实践1小时。然后,另外课后的习题做起来,课堂派的题也很简单,可以考虑考虑。
各位20级的同学,最近感谢大家的积极关注。我一直说,大家不要期待图灵班能给予大家太多的东西,希望大家要降低期望值。图灵班一直都做得非常不够,师资有问题是肯定的,以后各种安排,包括时间、场地,能给大家的真的真的非常有限。一直我都感觉非常抱歉。图灵班的意义在于大家为了一个共同的理念、目标,一起学习。图灵班的老师就是你们自己,其他人都只是辅助作用的,甚至可能是起到负面作用。希望大家能多了解这个读书小组,慎重考虑。
10月11日下午4点,131实验室。新生25人。
#include <stdio.h>
int main()
{
unsigned char a = 255;
printf("a + 2 == %d \n", a + 2);
printf("a^5 == %d \n", a * a * a * a * a);
a += 2;
printf("a + 2 == %d \n", a);
a = 255;
a = a * a * a * a * a;
printf("a^5 == %d \n", a);
a = 255;
a = a * a * a * a * a * a;
printf("a^6 == %d \n", a);
return 0;
}
请问以上程序的输出是什么?可以使用计算器,但是在给出答案前先不要编译执行该程序。
其实,整个脉络都是非常清晰的。现在只是具体化而已。如果你不清晰的话只需要理解到:程序 = 数据结构 + 算法。
目前语法已经不会成为重点去讲解了。那么剩下就是数据结构入门:数组、链接表、BST。算法:排序、搜索、树相关的算法。再稍微深入就是:堆、栈这样的结构。然后算法再深入一点就是广度优先、深度优先。最后,如果可以希望再有一点点DP。大概就是这样。其中穿插讲解一点点数论小知识。希望大家了解这个框架。
我大致把它表达为这样的一份指南,很标准化的内容了。没什么新鲜的东西。
各位同学,就我刚才改了几份作业来说,我看到一个问题,这个问题不知道什么课本会教。但是,你们肯定没想。我一直提示过很多次,估计也没怎么看,或者看了也不理解。什么问题?函数的定义问题。为什么一个函数要这样定义,不能那样定义。注意,这绝对不是语法问题。下面举个例子,第二周作业3,写一个素数筛法。理解错题意的我都不说了。就说说,你们认为这个函数应该怎么定义?下面是大家的代码:1、void ans(int n,int l,int r) 2、int* create_prime(int range); 3、int find(int n) 4、int is_primer(int b,int arr[]); 你认为哪一个是自己想要的呢?还有一个问题,到底是在这个函数外动态申请一个数组,还是在函数内形成一个数组传到函数外?
我很想提醒新生两点:第一,真的不必然会有老师教你;第二,你们的思考真的太少。仅有的时间都在忙碌,没有思考,这是可悲的。
今天有同学对我说,学了线性代数不知道怎么用。虽然我今天也讲了一个应用,而且我还可以讲很多的应用,但是估计也满足不了大家迫切“不起来”的需求。所以,我的意见是,大家不要太迫切要“用”,把数学作为一种语言去看待更好。打个比方,我在课堂派出的Fibonacci数的习题。矩阵只是一种描述工具。同样,在量子计算中,矩阵也是一种描述工具,没有这种工具,估计也就没有量子计算了。