首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >行为怪异的循环C

行为怪异的循环C
EN

Stack Overflow用户
提问于 2013-07-30 09:57:22
回答 4查看 168关注 0票数 1

我偶然发现了一个持续存在的问题,似乎没有一个合理的解释。问题似乎存在于for (i = size - 1; i >= 0; i--) {etc.}的for循环中,其中size是存储在内存缓冲区中的文件的大小,i是一个无符号整数。它不是在i == 0时停止,而是封装起来--从而导致i = 4294967295并导致分段错误。将条件更改为i > 0解决了这个问题。

不过,这不是很奇怪吗?我肯定缺少了for循环在C中运行的一些关键部分,它不遵循这个方案吗:初始化、检查条件、增量/减少、检查条件等等?

任何帮助都是非常感谢的!

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-07-30 09:59:13

无符号整数总是>= 0

代码语言:javascript
复制
for (i = size - 1; i >= 0; i--) {etc.}

如果iunsigned int,则为无限循环。

票数 8
EN

Stack Overflow用户

发布于 2013-07-30 10:13:08

让我们看看当i接近0时会发生什么。

  • i == 1:循环从i >= 0开始正常执行。从i中减去1。现在i包含0。
  • i == 0:循环从i >= 0开始正常执行。从i中减去1。因为i没有签名,所以它会被环绕。因此,i现在包含4294967295。
  • i == 4294967295:循环自i >= 0以来正常执行
  • 等等..。

解决方案是要么测试其他东西(如i > 0,如您的示例),要么在每次迭代和循环时增加i,而它小于文件的大小。

票数 2
EN

Stack Overflow用户

发布于 2013-07-30 10:33:23

根据C99标准:

6.2.5类型 9) ..。涉及无符号操作数的计算永远不会溢出,因为不能用结果无符号整数类型表示的结果将被减少,即大于结果类型所能表示的最大值的数字。

所以,在你的案例中会发生什么:

  • i == 1,因此i--会导致i == 0
  • i == 0,因此,i--会产生一个环绕和i == UINT_MAX.
  • i == UINT_MAX,因此i--会导致i == UINT_MAX - 1等等。

修复循环的一种方法是使用以下方法(https://stackoverflow.com/a/665773/676939):

代码语言:javascript
复制
for (i = size; i-- > 0;){
    /* yada yada yada */
}

另一种同样的方法是以下(https://stackoverflow.com/a/665758/676939):

代码语言:javascript
复制
unsigned fake_i;
for (fake_i = size; fake_i > 0; i--){
    unsigned i = fake_i - 1;
    /* Do something with i */
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17943893

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档