有一说一,回想学过的这么多学科,C语言可能是自学起来道路最坎坷的。
不是说它难,走对了其实还蛮简单的,问题在于入门前的每一步,乱七八糟的路都太多了。
从写第一个代码开始,用什么软件,VC6、dev、VS、VSCODE?
你会发现可能你的教材用VC6,然后一搜一堆人叫你别用,接着大佬A让你用dev,大佬B说VS是宇宙第一IDE,大佬C说Emacs或者vim。大佬D说自己配环境写命令行啊,反正你迟早要会,还有个不知道哪来的古代遗老让你用turbo C的。
你可能瑟瑟发抖地问一下,可是教材上用这个欸,然后发现大家开始说这本教材这个问题那个问题的,接着有人跳出来说这本书很经典当初就是看这个入门的,有人指责这人别误人子弟。
然后他们可能就自己吵起来了,留下懵住的你。
咋回事,能作为学校教材,清华大学出版社的东西还不靠谱的?
接着你有很多选择,听从其一或者跟着教材。
然后你可能就会遇到包括但不限于
1.不会配环境,配半天
2.scanf报错不给用,有人让你改成scanf_s,成功了一会然后学到字符串的时候翻车了
3.照抄教材的void main或者main结果不过编译
4.试图写hello world结果你的wolrd一闪而过,弹出个黑框秒退不给你hello
等问题
(这尚且还假定了你是一个非常细心的人,不至于把stdio写成studio,把main写成mian,把;写成;把双引号括过头写出了printf("%d, a")或者用了单引号,眼睛不瞎没把%lf抄成%1f,没漏抄这个字符没多写半个花括号等一系列个人问题)
作为一个小白你搞不明白main是什么玩意,人家跟你说程序的入口你也一愣一愣的
关于怎么写,有的人跟你说,void main就不用return 0,int main就要
有的人跟你讲什么直接写main是C89标准的东西,会默认类型为int但C99废除了
有人跟你说标准写法只有int main(void)和int main(int argc, char *argv[]),开始扯什么c里表示函数任意参数和c++里表示无参数这种话,接着有硬件佬出来说什么环境下就会写void main又没操作系统而且跑起来就死循环要啥返回值,语言是工具不要死守着标准当语言律师
接着他们可能又吵起来了……
留下懵懵的你,看着一堆像魔法一样的文字和根本听不懂的解释,在风中凌乱,不知道该听谁的,而谁都希望你听他的。
再从一开始的输入输出,你可能看着教材上写着这样的东西
#include <stdio.h>
void main(){
int a,b,c;
scanf(&#34;%d,%d&#34;,&a,&b);
c=a+b;
printf(&#34;%d&#34;,c);
}你可能不懂什么道理,但反正就照葫芦画瓢地记着
照着抄了一遍,遇到了前面说的可能是main不过编译,可能是scanf不给用之类的问题,总之你终于解决了,弹出了个黑框
然后你&#34;照着课本&#34;输入了个2,3,程序弹出来个莫名其妙的东西反正不是5
有人跟你强调scanf和输入要一致但你也不太明白这是啥意思
有人让你输入英文逗号,如果你小白一点你可能都不明白逗号怎么还分中英文的。
还有人让你改代码改成%d连写然后空格隔开,课本的代码又要改??
到底是这帮人不靠谱还是教材不靠谱,大学官方用的东西居然会不靠谱吗,很多人推荐的网课也会不靠谱吗。
你不明白为什么输入要带&,输出就不用,人家跟你讲什么指针、地址、值传递、类型匹配的你也不知道啥玩意听不懂,只能姑且这么记着一个要&一个不用。
然后到字符数组又开始翻车了。
接着又是老生常谈的问题,你可能看到教材跟你说什么,数组名同时也是数组的首地址。
你信了他的话,然后到二维数组传参的时候又开始懵了,为什么另一个维度不一样就会报错?不是说是首地址吗,传的是首地址啊。
再到学运算符的时候,可能你会发现书本还给你出一道这样的题。
int n = 3;
printf(&#34;%d %d&#34;,n, n++);或者
int a, i = 3;
a = i++ + i++;
printf(&#34;%d&#34;, a);且不说这东西一眼看过去就不想看。
你会发现它的运行结果跟你想的还不太一样?
于是你可能去搜索资料,试图理解。
然后一会听到这个人跟你讲优先级,那个人跟你讲压栈,那个人跟你说写这种代码等着被炒,还有个人贴着什么看不懂但看起来好高大上的英文条例,说着什么序列点啊求值顺序啊未定义行为这种课本根本没跟你讲的东西。
而且你发现这代码好像真的不同的软件跑起来真的不一样欸……咋回事。
再到一个分水岭,指针。
你终于开始接受这个设定,整数是int,&#34;小数&#34;是float或者double,double精度更高。原因是什么电脑只认识二进制还是哪个大佬提的什么IEEE754反正有这么一回事就对了,也不知道为什么小数要叫浮点数,char对应字符,也有个什么ASCII表可以对应到一个数字。
虽然字符还分正负这种事情有点离谱,但一想到它其实是个数字也还能接受。
然后你突然看到代码上写着这样的东西:
int a;
int *p = &a;
*p = 3;
printf(&#34;%d&#34;, a);*p是啥子东西?指针?指针是啥玩意???
感觉就像数学里的y=x你突然告诉我x是个皮球一样。
你迷迷糊糊的感觉*p应该是个整体,接着你看到了另一种写法
int a;
int *p;
p = &a;
*p = 3;
printf(&#34;%d&#34;, a);到底是*p=&a还是p=&a……而且一会*一会&的真的看起来跟乱码一样很掉san
在这种模模糊糊的认知下,有些课程可能就开始让你写(struct student *)malloc(sizeof(struct student)),开始搞什么学生管理系统了。
然后FILE*又是什么东西?
——而扯了半天,这一切都还停留在入门基操。
<hr/>那么回到题目,自学C语言的最恐怖的地方是什么?
首先从资料上,C语言的教学资料,靠谱的太厚太专业太晦涩容易抓不住主线,并且慢,比如C primer plus到第7章写了176页才跟你讲if语句。而简略点的一般又不太靠谱,似是而非,有时甚至错漏百出。从大学教材到网课很多都这样。
搜索或者问人的结果也是各种见解鱼龙混杂,作为新人并不好判断。
尤其有时候一个知识点,一个人跟你说这个是错题,是病句,另一个人好像头头是道的跟你从硬件上分析这分析那的,乍一看好像后面那个人才是懂得多的巨佬。所以说真的不好判断。
哪怕好不容易判断出谁是“龙”,如果不是那种很会嚼碎的前辈,可能他说出来的话你也听不懂,龙的话也不一定就对,比如一上来就学配环境这件事真不好说是好是坏,各有优略。
再一个,C语言本身也是一套人为设计的东西,是规定。
这种规定并不一定符合一开始的直觉,像a[10]大概还能凭直觉猜到是10个数,但是&a是什么玩意,*p又是什么东西,这是逼着你学习的,你没法靠直觉“推理”。
术语与规定的理解也可能有偏差或不太愿意接受。
比如,一个式子怎么还会有“返回值”这种东西,返回又是返回哪里啊,代码不是一直在往下执行吗。
比如,想当然地觉得x的平方就是x^2,成功过了编译,以为完事大吉然后蹦出个莫名其妙的答案。再比如知道有个函数叫pow,于是写了个pow(x, 2) % 10然后发现怎么报错了。x=6,6的平方等于36,36怎么就变成小数不给对10取余了?
很多新人可能就卡在想不明白,或者不愿意接受这种一些语法规定,需要一个“这是规定”以外的理由,偏偏这的确是规定。
而一说到规定,就觉得死记硬背,不能理解,就觉得学习痛苦。等等等等,诸如此类。
因此自学C语言非常检验一个人的自学能力,或者运气。
比如自学能力强,不会被没见过的东西吓到,不会自己瞎想而不经过验证地&#34;举一反三&#34;,不会试图自己瞎理解而不看资料,不会尽可能拒绝学习新知识,不会对一门学科有抗拒心理,有在零基础的情况下直接判断出什么是死规定、什么需要理解的能力,有快速阅读,不完全阅读,建立空中楼阁的能力,学习比较有耐心细心,不会盲从于大学教材与高人气网课,会有意识地把一些知识点和某种直觉联系上,或者能在训练过程中自然而然地培养这种直觉,等等等等。
或者另一种比较常见的路线,先在或对或错、似是而非的认知上前进了一定的程度,但总归先找到一条起码能运作的路线,回过头再遇错则纠错,至少这时已经具备一定的码力了,也开始听得懂一些专业词汇。
再比如运气好,恰好遇到了对胃口又没什么知识上的毛病的资料,遇到了靠谱又有耐心又善于教学的人。从而不走弯路。
<hr/>所以简单来说,学C如果思维对上线了,资料也靠谱,其实是蛮轻松也蛮快的。
而最恐怖的就是,思维不一定对得上线,很多资料也不靠谱。而自学要靠自己去克服这些,甚至可能自己都意识不到问题出在这,只是模模糊糊地觉得学起来磕磕碰碰的,要说哪里难可能都说不上反正就是难。
一个人如果能自己跨过来,甚至学得蛮轻松的,有时真的可以说这个人在一定程度上具备学习C语言的天赋。 |