前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >校长讲堂第七讲

校长讲堂第七讲

作者头像
一头小山猪
发布2020-04-10 10:16:48
3390
发布2020-04-10 10:16:48
举报

语义“陷阱”

一个句子可以是精确拼写的并且没有语法错误,但仍然没有意义。在这一节中,我们将会看到一些程序的写法会使得它们看起来是一个意思,但实际上是另一种完全不同的意思。 我们还要讨论一些表面上看起来合理但实际上会产生未定义结果的环境。我们这里讨论的东西并不保证能够在所有的 C 实现中工作。我们暂且忘记这些能够在一些实现中工作但可能不能在另一些实现中工作的东西,直到以后讨论可以执行问题为止。

3.1 表达式求值顺序

一些 C 运算符以一种已知的、特定的顺序对其操作数进行求值。但另一些不能。例如,考虑下面的表达式: a < b && c < d C 语言定义规定 a < b 首先被求值。如果 a 确实小于 b,c < d 必须紧接着被求值以计算整个表达式的 值。但如果 a 大于或等于 b,则 c < d 根本不会被求值。 要对 a < b 求值,编译器对 a 和 b 的求值就会有一个先后。但在一些机器上,它们也许是并行进行 的。 C 中只有四个运算符&&、||、?:和,指定了求值顺序。&&和||最先对左边的操作数进行求值,而右边的操作数只有在需要的时候才进行求值。而?:运算符中的三个操作数:a、b 和 c,最先对 a 进行求值,之后仅对 b 或 c 中的一个进行求值,这取决于 a 的值。,运算符首先对左边的操作数进行求值,然后抛弃它的值,对右边的操作数进行求值。 C 中所有其它的运算符对操作数的求值顺序都是未定义的。事实上,赋值运算符不对求值顺序做出任何保证。 出于这个原因,下面这种将数组 x 中的前 n 个元素复制到数组 y 中的方法是不可行的: i = 0; while(i < n) y[i] = x[i++]; 其中的问题是 y[i]的地址并不保证在 i 增长之前被求值。在某些实现中,这是可能的;但在另一些实现中却不可能。另一种情况出于同样的原因会失败: i = 0; while(i < n) y[i++] = x[i]; 而下面的代码是可以工作的: i = 0; while(i < n) { y[i] = x[i]; i++; } 当然,这可以简写为: for(i = 0; i < n; i++) y[i] = x[i];

3.2 &&、||和!运算符

C 中有两种逻辑运算符,在某些情况下是可以交换的:按位运算符&、|和~,以及逻辑运算符&&、||和!。一个程序员如果用某一类运算符替换相应的另一类运算符会得到某些奇怪的效果:程序可能会正确 地工作,但这纯属偶然。 &&、||和!运算符将它们的参数视为仅有“真”或“假”,通常约定 0 代表“假”而其它的任意值都代表 “真”。这些运算符返回 1 表示“真”而返回 0 表示“假”,而且&&和||运算符当可以通过左边的操作数确定 其返回值时,就不会对右边的操作数进行求值。 因此!10 是零,因为 10 非零;10 && 12 是 1,因为 10 和 12 都非零;10 || 12 也是 1,因为10 非零。另外,最后一个表达式中的 12 不会被求值,10 || f()中的 f()也不会被求值。 考虑下面这段用于在一个表中查找一个特定元素的程序: i = 0; while(i < tabsize && tab[i] != x) i++; 这段循环背后的意思是如果 i 等于 tabsize 时循环结束,元素未被找到。否则,i 包含了元素的索引。假设这个例子中的&&不小心被替换为了&,这个循环可能仍然能够工作,但只有两种幸运的情况可以 使它停下来。 首先,这两个操作都是当条件为假时返回 0,当条件为真时返回 1。只要 x 和 y 都是 1 或 0,x & y和 x && y 都具有相同的值。然而,如果当使用了出了 1 之外的非零值表示“真”时互换了这两个运算符,这个循环将不会工作。 其次,由于数组元素不会改变,因此越过数组最后一个元素进一个位置时是无害的,循环会幸运地停下来。失误的程序会越过数组的结尾,因为&不像&&,总是会对所有的操作数进行求值。因此循环的最后一次获取 tab[i]时 i 的值已经等于 tabsize 了。如果 tabsize 是 tab 中元素的数量,则会取到 tab中不存在的一个值。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-10-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微光点亮星辰 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 语义“陷阱”
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档