武汉c培训
达内武汉中心

15271940953

热门课程

武汉c语言培训:C的陷阱和缺陷

  • 时间:2017-09-18
  • 发布:武汉C++培训
  • 来源:c语言教程

今天带给大家的干货知识是C的陷阱和缺陷

一、词法陷阱:
      = 不同于==不要在程序中将两者写错,小心。将表达式与常量比较时,可将常量放在左边。
       &和| 不同于&& 和 ||.
      词法分析中的贪心法:每个符号应该包含尽可能多的字符。如果(编译器的)输入流截至某个字符前都已经分解为一个个符号,那么下一个符号将包括从该字符之后可能组成一个字符的最长字符串。如y = x/*p,那么/*将作为一个符号对待。
     如果一个整形变量第一个字符是0,那么该常量被视为8进制数。
        Char c = ‘cxf’。在vc和Gcc中,依次用后一个字符覆盖前一个字符,最后得到的整数值是最后一个字符的整数值。

二、语法陷阱:
      c变量声明由类型和一组类似表达式的声明符组成。声明符与表达式类似,对他求值返回一个声明中给定类型的结果。如float f,((f))。知道了如何声明一个变量,那么该类型的类型转换符就很容易得到了:将声明

的变量名和分号去掉,再将剩余的部分用个括号“封装”起来即可。如 float(*h)(),则float(*)()就是“指向返回值是浮点类型的函数的指针”的类型转换符。(*(void(*)())0)()调用地址为0位置的的例程。
       运算符优先级:单目运算符,算术运算符,移位,关系,逻辑,条件, 赋值。
       switch语句中case中,不要忘记break,若刻意要省略,请加注释。
        C语言中只有一维数组,而且数组的大小必须在编译期间就作为一个常数确定下来。多维数组是通过一维数组仿真的,因为数组的元素可以是任何对象,当然也可以是数组。
对数组,我们只能做两件事,确定其大小,以及获得指向该数组下标为0的元素的指针。其它的有关数组的操作,实际上是通过指针进行的。

三、语义陷阱:
          空指针并不等于空字符串。编译器保证由0转换而来的指针不等于任何有效的指针。当将0赋值非一个指针变量时,绝对不能企图使用该指针指向的内存中存储的内容。
         在使用范围时,使用不对称边界方式。第一个是“入界点”(序列中第一个被占用的元素),第二个是“出界点”(序列中第一个被释放的元算)。For(int I = 0 ; I < 10; i++)。尽量不要使用For(int I = 0 ; I <=9; i++)。
          数组的下标如果用入界口加出界口来表达(即10个元素,其下标为0 <= n < 10 ),则元素个数即为上界与下界之差,即下界。若为空,则上界等于下界。任何情况下上界也永远不可能小于下界。
尽量采用非对称边界法。

从理论上说,一个信号可能在C程序执行期间的任何时刻上发生,甚至可能出现在某些复杂的库函数(如malloc)的执行过程中。因此从安全的角度讲,信号的处理函数不应该调用上述类型的库函数。基于同样的原因,从signal处理函数中使用longjump退出,通常情况下也是不安全的:因为信号可能发生在malloc 或者其它库函数开始更新某个数据结构,却又没有最后完成的过程中。因此signal处理函数能够做的安全的事情,似乎就只有设置一个标志然后返回,期待以后主程序能够检查到这个标志,发现一个信号已经发生。

然而,就算这样做也并不总是安全的。当一个算术运算错误引发一个信号时,某些机器在signal处理函数返回后还将重新执行失败的操作。因此对于算术运算错误,signal处理函数的惟一安全、可移植的操作就是打印一条出错消息,然后使用longjump或exit立即退出程序。

当一个程序异常终止时,程序输出的最后几行常常会丢失,原因是缓冲。

四、预处理器:
        不要忽视宏中的括号。
       宏不是函数。将宏中的参数都加上括号,将整个结果表达式也括起来。防止副作用。
       宏不是语句:#define assert(e) ((void)((e)||_assert_error(_FILE_,_LINE_)))
       宏不是类型定义;不要用#define定义类型,而是用typedef定义新类型。

五、可移植性:

因为字符串常量可以用来表示一个字符数组,所以在数组名出现的地方都可以用字符串常量末端替换。     如:    "0123456789"[n%10]
  注意C标准的变化,新特性的使用。

c标准所能保证的只是,c实现必须能够区别出前6个字符不同的外部名称,且并没有要求区分大小写。避免诸如:print_char(),print_int()等
  整数长度的相对长度规定:short类型的值肯定能被int型容纳,int型肯定能被long型整数容纳;一个普通(int类型)整数足够大以容纳任何数组下标;字符长度由硬件特性决定。
  随机数最大值:RAND_MAX