读《C陷阱与缺陷》

        第一次接触C语言是在大一的《C程序设计》课程中,所选用的教材是谭浩强教授的C语言版本。这本书涉及的内容很多,几乎涉及到C语言的方方面面。对于语言的细节,比如语法格式等讲的非常详细。尤其是在指针部分,从单纯的指针概念到指针数组、返回函数的指针再到指向函数的指针,这部分语言精华让当时大多数的程序语言学习者往往陷入迷茫的状态。这门课程是我进入大学本科以来接触的第一门程序设计语言,当时上课的老师告诉我们这门程序设计语言是我们今后学习其他程序设计语言的基础。程序设计语具有的一定的相似性,从后来的学习中确实也可以得到证实。在以后的学习中,我也接触和学习了Java程序设计语言,Java语言与C语言有着非常大的区别。C语言面向过程,Java语言面向对象,更适合开发大型的应用软件。但是这并不意味着C语言的落后,在单片机的学习中我们逐渐被C语言易于对硬件的操作所吸引,虽然当时上课教学的语言是汇编语言,但是C语言的单片机程序设计,摆脱了汇编语言的复杂性和不易理解。后来我们相继开设了嵌入式、Linux网络运维等课程,在这些课程中,我们更加清晰了认识了C语言在接近硬件底层、OS等方方面面的巨大优势。

       初学者,学习C语言往往纠结于详细的语法规则,再加上缺乏相关的语言基础,会对这门语言产生厌学的情绪,当然这也是可以理解的。当时,我在学习C语言时,也曾陷入到C语言忙忙的语法规则中不能自拔,尤其是在指针部分尽管当时教授我们课程的老师耐心给我们讲解,但是囿于课时的限制和教学大纲的要求,我们在很短的时间内学习了包括指针数组、数组指针、指向函数的指针等内容,所以也没能真正理解这些知识点。后来大一寒假,我把这本书带回家反复看并将上面给出的程序例子和课后大部分的习题一一在编译软件中编写和实现,终于悟出了这门程序语言的一些奥秘。

       对于这门语言的学习并没有止步于课程的学习,这门语言后来对我大学时期的发展或多或少的起到了一些影响。大一下学期,我们开设了C语言的课程实训,课程的时间很短,当时我们整个信息工程专业都在一起上大课。实训内容的重点知识是指针的综合应用,因为在寒假的时候我在家里再次复习了这门程序设计语言,尤其是在指针部分有了更多的了解,所以并没有对指针产生心理阴影。课程设计的内容是指针和文件操作的综合应用,要求我们用指针构造链表,实现数据的添加、删除、文件的打开和保存操作,其实就是所谓的学生学籍管理系统,虽然并不十分清楚为什么学了C语言就一定要写个学生学籍管理系统或者什么职工信息管理系统,甚至现在想来也觉得这些个东西很弱,但是这个课程的设计对于帮助理解指针确实是有帮助的,当然了前提是这些代表的实现是你自己亲手用键盘敲击出来的而不是单纯的复制张贴别人的代码。

        大一结束,我们对于C语言的学习也就告一段落了,但是,我的行程却还没有结束。后来,我们软件学院举办了ACM程序设计大赛,经过初赛选拔的同学可以参加暑期的程序设计大赛培训,在培训结束的时候经过第二次选拔可以代表学校参加重庆市的大学生程序设计大赛。在培训的时候,因为不是软件专业,所以还没有学习数据结构、离散数学这样的课程,因而对“算法”的概念并不清楚,后来经过一段时间的培训才终于对算法有了一定的了解,再后来我第一次参加重庆市的ACM程序设计大赛,我和我的团队居然获奖了而且是我们学校派出的代表队中取得成绩最好的一支,这也极大地鼓励我继续加强这方面的学习。在2014年的时候,我和我的团队在ACM程序大赛中再次获得较为理想的成绩,拿到了一等奖。

       如今几年过去,我也开始接触了一些硬件上的编程,包括ARMMT7688ESP8266ZigBee等硬件,这些东西虽然并不是纯的C语言编程,但是他们依旧是C语言的“异构体”,这些东西使用了和C几乎一样的语法规则和流程控制。在空余的时间我们在不断学习C语言知识,后来一次回家无意中看到了《C陷阱与缺陷》,这本书是我在大二的时候买的,虽然买来了但是因为种种原因一直丢弃在一旁没有好好阅读。最近又再次拿起这本书,学习程序语言中的陷阱,希望在以后的编程中能够汲取编者的智慧,为自己避免不必要的麻烦。这正如编者在前言中所述的一样,任何一种程序设计语言,总存在一些语言特性。C语言中那些容易导致人犯错误的特性,往往也正是编程老手们为之吸引的特性。因此,只要大多数程序员在成长为C编程高手的路上,犯过的错误真是惊人的相似!

       尽管学习C语言有一段时间了,但是在这本书中再次学到了许多的知识,包括词法、语法、语义等方面的陷阱。书中给出了许多在程序设计中国许多微小的细节,这些细节可能在我们实际的编程已经发生,甚至给我们程序的调试带来了不小的麻烦。因为正如书的编者所述,有的错误极具伪装性和欺骗性。

while(c=='\t' || c ='' || c=='\n')

c=getchar();

         对于这样的例子,在我编程的时间中确有发生过,因为一个等号的失误造成优先级的不同,自然而言编译报错。书中所述的例子,确实可以称得上经典,有的例子可能也是我们这些编程者压根就没有想过的,你或许觉得这些东西没有意义,但是有时真的是我们编程错误中最经典的来源。这些程序语言的陷阱,恰恰反映出了程序的设计人员在某些方面的确实。以条件判断为例,通常我们的判断语句可能写成如下形式:

if(flag==9)

        但是实际上我们可能因为疏忽写成了if(flag=9),因为一个等号的疏忽使条件判断语句编程了赋值语句,因为9不为零所以条件判断语句的值时钟为真,这样造成的结果是使得条件语句后面的可执行语句将执行,从而造成隐形的错误。因此,以上条件判断语句可以写成:

if(9==flag)

        当然,书中也不乏经典的程序小例子,例如写出一个测试程序,编译器是否支持嵌套注释。第一次看到这个题目确实觉得很难入手,因为在我所使用和接触的很多编译软件本身就是不支持嵌套注释的,那么如何通过程序来判断编译器是否支持嵌套注释呢。书中提供了一个经典的解法:

/*/*/0*/**/1

这种解法主要利用了编译器做词法分析的“大嘴法”原则,如果编译器允许注释,那么上式分解成:

/*  /*  /0  */  *  */  1

上式的值将为1。但是如果不支持嵌套那么上式将分解成:

/*/*/  0*  /**/  1

0*1,其值为0。我的编译器是VC6.0,是不支持嵌套注释的,因此表达式求值的结果为0,与上面的分析结果是一致的。除了这些,也有一些程序小技巧,例如巧妙使用以为运算来代替除法运算,加快程序的运行速度:

int  mid = ( hi + lo ) / 2;

改写成:

Int  mid = ( hi + lo )  >>  1;

         书中也告知了编程者许多陷阱,例如作为语句结束标志的分号、else引起的悬挂问题等等,这些都是在我或者你编写程序的过程中实实在在发生过的。

         学完这本书,还是有很大的收获,这是一本值得研读的书。在以后的学习中,我也将继续学习C语言中更加精华的知识,深入理解硬件底层特性,希望能以此为契机,获得更大的进步。

 

 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值