对今天C语言机考的吐槽和感想

考试内容

第一个函数,拼接字符串,并且要求该函数能够对异常进行处理,函数只接受两个字符指针,没有告诉我字符串1所在的数组长度,所以无法避免有时候会超出字符串1所在数组的内存空间造成内存访问异常。我绞尽脑汁都想不出来如何避免由于结果字符串过长导致的内存访问异常,除非动用C库函数,而我又担心使用库函数会扣分,所以就直接放弃对异常处理了。但愿影响不大。

第二个函数,插入字符串,也是要求能够对异常进行处理,函数接受两个字符指针,和插入位置索引。这个稍稍知道,大致应该是如果插入位置大于了字符串1的长度,就出错,额,但是回到宿舍又想,如果插入位置小于0的话,也应该出错,当时没想到这个情况。我认为该题考查错误的“重点”在于判断插入位置是否大于字符串1的长度,而不是判断那个插入索引值是否小于0。但愿影响不大。。。

总结:这两个函数我均用C语言基本的语句来实现的,没有借助任何库函数,但是在不借助库函数的前提下,不管是上述哪个函数,都无法做到对异常的完美处理。

如果非要考虑特殊情况,那么还可能出现如下情况:

  1. 传递的字符指针不合法,比如,传入一个未经初始化的指针,它的值是随机的,那么也会出错,但这根本没法预料;
  2. 程序堆栈已满或者溢出,造成函数中的局部变量的内存无法正常分配,(多级函数调用的时候可能会出现堆栈用完的情况,比如一个错误的无法停止的递归函数);
  3. ……

这些情况都不是简简单单能够处理的,所以总的来说,对考试题目的解答实际上并不能做到完美,题目也没有说清楚到底是处理哪些异常。

C语言是一门追求高效的高级语言

如果能够让程序员自己预料可能存在的错误并且尽可能去避免,而不是依赖函数本身来完成对错误的检查,那无疑更贴近“追求高效”的目的。

正如C语言从来不检查下标是否越界,它把这个“包袱”扔给了程序员自己,让程序员自己保证不会出现下标越界,这更印证了本节开头的观点。
假设C语言自己会检查下标是否越界,那么我们每次使用下标的时候,它就会用一次判断来检查下标是否越界,假如我使用了一万次下标,他就要比较一万次,天哪!如果一个有良好技巧且追求高效率的程序员遇到这样的C语言,他估计会崩溃!就一个“优秀的”程序员本身来说,肯定是会想办法避免下标越界的,如果C语言“自作多情地”再检查一遍,效率岂不是太低?何况C语言中,下标的本质是“以数组其实地址为基址的内存偏移量”,这也简化了C语言对数组和对下标的处理。以“牺牲”一点安全性换取这么多的“高效”,这确实是个好主意!C语言本来就是为了高效灵活而诞生的,很多人喜欢C语言就是因为它的灵活和高效,如果一切都限制、都检查得太死,就让C语言暗淡太多了。

我的感想

结合这次机考,我认为函数应该“安分守己”完成自己的“本职工作”,写函数的时候应该“假设”所传递的实际参数是正确的、不会出现问题的,函数按照正常过程完成功能就行了。同时我们调用函数的时候,应该保证传递给函数的实际参数是正确的、不会出现问题的,需不需要检查参数,由调用者的实际情况决定,需要检查,那么我就在调用函数之前检查参数是否有问题,再判断是否需要调用函数,如果能够断定参数没有问题,那么就不检查参数而直接调用函数,这样就能提高很多效率。总的一句话概括就是:函数完成函数自己的事情,“错误检查”和“错误避免”应该交给“外部”处理。(这个“外部”包括调用函数的地方,甚至包括程序员自己。)

连标准的C库函数都没有对内存访问越界进行检查。这也支持了“C语言是一门追求高效的高级语言”这一说法。

标准C库函数中的这些函数之所以没有对可能出现的错误进行检查,也许是为了提高程序的执行效率,把避免错误的任务交给了程序员自己,让程序员自己评估可能发生的错误以及尽可能地去避免错误,我想这样的做法是最好的。

标签: none

添加新评论