《C陷阱与缺陷》 第三章 语义“陷阱”

来源:互联网 发布:python cms 管理系统 编辑:程序博客网 时间:2024/06/06 00:18

3.1 数组与指针

两点概念:1.C语言只有一维数组,且数组大小在编译器已经定下。2.对于一个数组,我们只能干两件事:确定数组大小和得到数组下标为0 的元素的指针。
数组下标原理: Array[ n ]    等同于  *(Array+n)
对于二维数组,可以理解为是以数组为元素的数组。

3.2 非数组的指针

C语言中字符串常量包含了字符串中所有字符以及一个‘\0’,在为字符串动态分配内存时应该考虑最后一个'\0'。

3.3 作为参数的数组申明 

int strlen(char* str){}

int strlen(char str[]){}

的效果是完全一样的,str会被看作是指针,sizeof(str) = 4。

3.4 避免“举隅法”

这节说的是,要清楚指针指向内存的情况,不要将一个指针当作一个变量去理解(虽然有时候用起来感觉差不多,但心里始终要有个数)。有时候两个指针指向同一个内存,操作一个指针,相当于改变了指向共有内存的状态,这时候心里要有数。

3.5 空指针并非空字符串

不要将指向NULL的指针当空串用(虽然感觉一样,但其实不一样),不信可以在VS2005上试一下如下代码:
#include   <stdio.h>     int   main(int argc, char *argv[])   {   char   buffer[10];   char *p = NULL;printf( "%s\n",   p);buffer[0] = '\0';char *q = buffer;printf( "%s\n",   q);return   0;   }

3.6 边界计算与不对称边界

这节很长,前半段我看懂了,说了这样一个边界问题: 10米路,每米有根电线杆,共多少根?
这其实是两个闭区间:[0,10],是11个,而一般大条的人觉得直接是10个,也就错了。一般来说,以程序员的经验,写for循环做做遍历的话应该是左闭右开的区间比较好,比如以上的应该是for(i = 0;i<=10;++i); 写代码时候一般用for(i = 0;i<11;i++);比较多,这样比较清晰而且平常。关键是个边界的习惯。

3.7 求值顺序

说了这样一个情况:
if(0 == i && ++a == 1 ){}
以上一个表达式,当 i ! = 1时,判断铁定为false,所以,代码是不会执行++a 这个操作的(对 || 也同理,如果前一个判断为true,后一个判断也不会执行)。如果不知道的话,可能会以为++a铁定执行,那就错了。

3.8 运算符 && ,||  和 !

这一节说的是不要将&& 和& 什么混用什么的。。。还有&& ,|| ,! 的结果不是1就是0。

3.9 整数溢出

这里说的是有符号运算要当心溢出。这是个基本功的问题。

3.10 为函数main提供返回值

说的是最好给main 加上 int 的返回值。

原创粉丝点击