C语言缺陷与陷阱(3)

语义分析
(程序员本意是希望表示某种事物,而实际表示的却是另外一种事物)
【C语言缺陷与陷阱(3)】1.指针和数组
数组值必须注意的两点:(1)C语言只有一维数组,且数组大小必须在编译期作为一个常数确定下来;(2)对一个数组只能进行:确定该数组的大小,以及获得指向该数组下标为0的元素的指针。
若一个指针指向的是数组中的一个元素,那么给该指针加1就能够得到该数组中下一个元素的指针,该该指针减1就能够得到该数组中上一个元素的指针。
只有在两个指针指向同一个数组中的元素时,对两个指针相加、减才有意义。
2.非数组的指针
对于字符串常量,不但包括字符串中所有字符,还包含一个空字符(’\0’)的内存区域地址。
在进行常量字符串的复制等操作时,要注意:(1)利用malloc申请分配的内存是否成功;(2)分配的内存使用之后应及时释放;(3)分配内存的大小应为strlen(str)+1。
3.作为参数的数组声明
使用数组名作为参数,那么数组名会立刻被转换为指向该数组第一个元素的指针。
如果指针参数为一个数组,则表示指向某一数组的起始元素的指针。
4.避免“举隅法”(以含义更宽泛的词语来代替含义相对较窄的词语,或者相反。如以整体代表部分,或者以部分代表整体)
复制指针并不同时复制指针所指向的数据
5.空指针并非空字符串
当常数0被转换为指针使用时,这个指针绝对不能被解除引用。即,当将0赋值给一个指针变量时,绝对不能企图使用该指针所指向的内存中存储的内容。
6.边界计算与不对称边界
在C中,一个数组有N个元素,则其下标从0~N-1.为了避免数组越界、“栏杆错误”等情况的发现,最好的处理方法是:用第一个入界点和第一个出界点来表示一个数值范围。
在处理循环时,运用--n>=0的效率比较高
7.求值顺序
在C中,只有&&、||、?:和,存在规定的求值顺序。
&&和||先对左侧操作数求值,只在需要时才对右侧操作数求值;
在a?b:c,先对a求值,根据a 的值再求b或c的值;
,(逗号运算符),先对左侧操作数求值,然后该值被“丢弃”,再对右侧操作数求值。(注意:分隔函数参数的逗号并非逗号运算符)
8.运算符&&、||和!
按位运算符&、|、~对操作数处理的方式是:将其视作一个二进制的位序列,分别对其每个位进行操作。(注意:负数的表示为其补码);
逻辑运算符&&、||、!对操作数处理的方式是:将其视作要么是“真”,要么是“假”。
9.整数溢出
无符号算术运算中,没有所谓的溢出;
若算术运算符的一个操作数是有符号整数,另一个是无符号整数,那么有符号整数会被自动转换为无符号整数;
若算术运算符的两个操作数都是有符号整数,溢出有可能发生,但溢出的结果是未定义的。
10.为函数main提供返回值
在C中main函数返回类型默认为整型,通过main函数的返回值来告知操作系统该函数的执行是成功还是失败。一般情况下,返回0代表程序执行成功,返回非0代表程序执行失败。

    推荐阅读