第三章 语义陷阱

3.1 指针与数组

C语言中只有一维数组,而且数组的大小必须字编译期就作为一个常数确定下来。数组中的元素可以是另外一个数组。
任何一个数组下标运算都等同于一个对应的指针运算。
int a[3];
除了a被用作运算符sizeof的参数这一情形,在其它所有情形中数组名a都代表指向数组a中下标为0的元素的指针,sizeof(a)是整个数组a的大小。
*a是数组a中下标为0的元素的引用,*(a+1)是数组中下标为1的元素的引用。

3.2 非数组的指针

在C语言中,字符串常量代表了一块包括字符串中所有字符以及一个空字符的内存区域的地址。
假设我们有两个这样的字符串s和t,我们希望可以借助常用的库函数strcpy和strcat。
char *r;
strcpy(r,s);
strcat(r,t);
这段函数的问题在于没有初始化r。

char r[100];
strcpy(r,s);
strcat(r,t);
但是这段函数又不能确保r足够大。

char *r;
r=malloc(strlen(s)+strlen(t));
strcpy(r,s);
strcat(r,t);
这段函数问题在于
一、malloc函数有可能无法提供请求的内存。
二、给r分配内存后应该释放。
三、未计算空字符的空间。
char *r;
r=malloc(strlen(s)+strlen(t)+1);
if(!r)
exit(1);
strcpy(r,s);
strcat(r,t);
free(r);

3.3 作为参数的数组声明

int strlen(char s[])与int strlen(char *s)一样
char hello[]="hello";
printf("%s\n",hello)与printf("%s\n",&hello[0])一样

3.4 避免举隅法

举隅:即以含义更宽泛的词语来代替含义相对较窄的词语,或者相反。
char *p="xyz",*q;
P的值是一个指向'x','y','z'和‘\0’4个字符组成的数组的起始元素的指针,
q=p;
P和q现在是两个指向内存中同一地址的指针,这个赋值语句并没有同时复制内存中的字符。两者中一个改变内容,另外一个也随之改变。

3.5 空指针并非空字符串

编译器保证由0转换而来的指针并不等于任何有效的指针。
出于文档化的考虑,常数0这个值经常用一个符号来代替。
#define NULL 0
当常数0被转换为指针使用时,这个指针绝对不能解除引用,即不能企图使用该指针所指向的内容中存储的内容。
(char *)0;

3.6 边界计算与不对称边界

C语言中一个拥有n个元素的数组,它的元素的下标范围是从0到n-1为止。
数组中实际不存在的“溢界”元素的地址位于数组所占内存之后,这个地址可以用于进行赋值和比较。当然如果引用该元素,那就是非法了。

3.7 求值顺序

C语言中只有四个运算符(&&、||、?、,)存在规定的求值顺序。
运算符&&和||首先对左侧操作数求值,只有在需要时才对右侧操作数求值。
逗号运算符,首先对左侧操作数求值,然后该值被"丢弃",再对右侧操作数求值。
注:分隔函数参数的逗号并非逗号运算符。
f(x,y)中的求值顺序是未定义的,而在函数g((x,y))中却是确定的。函数g中只有一个参数,先对x求值再丢弃x,接着求y的值。

3.8 运算符&&、||和!

误用移位符代替逻辑符可能产生结果相同的程序,但这只是巧合。
&和&&的求值顺序不一样。

3.9 整数溢出

C语言中存在有符号和无符号运算两类整数算术运算。
在无符号算术运算中,没有所谓的"溢出"一说。
如果是有符号和无符号数进行运算,那么有符号整数会被转换为无符号整数,"溢出"也不可能发生。
只有当爽法都是有符号整数时,可能发生溢出。解决方法可以是把双方都转换为无符号整数,(unsigned)a。

3.10 为函数main提供返回值

如果函数main并为显示声明返回类型,那默认为整型。
严格情况下我们需要在函数结束添加return 0;或者 exit(0);

C陷阱与缺陷(三)的更多相关文章

  1. 阅读《C陷阱与缺陷》的知识增量

    版权声明:本文为Focustc原创文章.转载请注明作者及出处. https://blog.csdn.net/caozhankui/article/details/35925939 看完<C陷阱与 ...

  2. 读书笔记--C陷阱与缺陷(一)

    要参与C语言项目,于是作者只好重拾C语言(之前都是C++,还是C++方便). 看到大家都推荐看看  C陷阱与缺陷(C traps and pitfalls),于是好奇的开始了这本书的读书之旅. 决定将 ...

  3. C陷阱和缺陷学习笔记

    这段时间把<C陷阱和缺陷>看了,没时间自己写总结.就转一下别人的学习笔记吧http://bbs.chinaunix.net/thread-749888-1-1.html Chapter 1 ...

  4. 读书笔记--C陷阱与缺陷(七)

    第七章 1.null指针并不指向任何对象,所以只用于赋值和比较运算,其他使用目的都是非法的. 误用null指针的后果是未定义的,根据编译器各异. 有的编译器对内存位置0只读,有的可读写. 书中给出了一 ...

  5. [C陷阱和缺陷] 第1章 词法“陷阱”

    有感自己的C语言在有些地方存在误区,所以重新仔细把"C陷阱和缺陷"翻出来看看,并写下这篇博客,用于读书总结以及日后方便自身复习. 第1章 词法"陷阱" 1.1 ...

  6. C语言学习书籍推荐《C陷阱与缺陷》下载

    下载地址:点我 凯尼格 (作者), 高巍 (译者) <C和C++经典著作:C陷阱与缺陷>适合有一定经验的C程序员阅读学习,即便你是C编程高手,<C和C++经典著作:C陷阱与缺陷> ...

  7. 读书笔记--C陷阱与缺陷(三)

    第三章 1. 指针与数组 书中强调C中数组注意的两点: 1)     C语言只有一维数组,但是数组元素可以是任何类型对象,是另外一个数组时就产生了二维数组.数组大小是常数(但GCC实现了变长数组..) ...

  8. c缺陷与陷阱笔记-第三章 语义陷阱

    1.关于数组和数组指针 数组的名字默认是常量指针,值不能改变的,例如 int a[]={1,2,3,...},这个a的类型时int *,所以如果有int *p,那么a=p是合法的,其他的指针类型,例如 ...

  9. 程序员必知的Python陷阱与缺陷列表

    本文关注的主要是python陷阱,具体而言,是指CPython,而且除非特别说明,所有代码示例都是在python2.7运行的. 我个人对陷阱的定义是这样的:代码看起来可以工作,但不是以你“想当然“”的 ...

随机推荐

  1. swith

    “开关”(Switch)有时也被划分为一种“选择语句”.根据一个整数表达式的值,switch语句可从一系列代码选出一段执行.它的格式如下: switch(整数选择因子) { case 整数值1 : 语 ...

  2. req.body取不到值的问题;

    随着express升级,bodyParser从express中被分离了出来,因此,在使用express新版本的时候,需要npm install body-parser 来安装bodyParser. 在 ...

  3. ListBox控件的操作与实现

    .NET FrameWork>參考>类库>System.Windows.Forms>ListBox类的属性 1. 属性列表:     SelectionMode     组件中 ...

  4. uva 10404 Bachet's Game(完全背包)

    题目连接:10404 - Bachet's Game 题目大意:由一堆石子, 给出石子的总数, 接下来由stan和ollie两个人玩游戏,给出n, 在给出n种取石子的方法(即为每次可取走石子的数量), ...

  5. NGUI Button 3中点击事件的触发

    NGUI事件的种类很多,比如点击.双击.拖动.滑动等等,他们处理事件的原理几乎万全一样,本文只用按钮来举例. 1.直接监听事件 把下面脚本直接绑定在按钮上,点击按钮触发的方法名必须为OnClick,当 ...

  6. Foundation NSMutableArray遍历,选取出符合条件的所有对象

    一.查找数组中一个元素,找到后立即返回 当遍历数组只需要返回其中一个符合条件的元素时,使用 indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, ...

  7. Lucene站内搜索的设计思路

    正好近期部门有一个小需求需要做商品的搜索,虽然最终由于工作量等原因先做数据库搜索,我依然用刚接触的Lucene弄了一套自嗨. 首先看需求:搜索:根据商品标题和内容搜索 没错,就这么简单! 我想了想,数 ...

  8. BZOJ 1606: [Usaco2008 Dec]Hay For Sale 购买干草( dp )

    -------------------------------------------------------------------- #include<cstdio> #include ...

  9. codeforces 451E. Devu and Flowers 容斥原理+lucas

    题目链接 给n个盒子, 每个盒子里面有f[i]个小球, 然后一共可以取sum个小球.问有多少种取法, 同一个盒子里的小球相同, 不同盒子的不同. 首先我们知道, n个盒子放sum个小球的方式一共有C( ...

  10. java集合分析(转载)

    参考文章:浅谈Java中的Set.List.Map的区别 Java 7 Collections详解 java中集合分为三类: Set(集) List(列表) Map(映射) Set和List继承自Co ...