【问题标题】:post decrement in while conditon in C在 C 中的 while 条件中后递减
【发布时间】:2011-03-21 05:16:15
【问题描述】:

我进行了搜索,但没有找到任何与我的查询相关的内容。 我目前正在调试一个 C 优化器,有问题的代码如下所示:

while( x-- )
array[x] = NULL;

在这种情况下应该发生什么?这个逻辑的结果是否应该在所有编译器中保持一致?

假设在这种情况下 x 的初始值为 5。

问题是程序崩溃了,我的理解是负数组元素引用造成的。

任何帮助将不胜感激。

【问题讨论】:

  • 数组永远不会被负值索引(前提是x 以非负数开头)。当x 变为0(随后递减为-1)时,无论如何都不会执行主体,因为0 的值被认为是假的。
  • 由于 while 循环的控制表达式的结尾是一个序列点,因此在这种情况下,无论您使用后增量还是前增量,我都不希望它有任何区别。除非我遗漏了一些东西,否则我不会期望 x 变为负数。是否有更多代码可以更清楚地说明这个主题?
  • @Sean:这会有所不同——预增量会提前一次迭代终止循环。
  • @Sean:我在回答中提供了一个带有 unsigned 索引的示例。索引是 unsigned(如果是)这一事实使得后增量(特别是 post)很重要。无论如何,如果您使用预增量,循环将在处理array[0]之前终止。

标签: c post while-loop optimization decrement


【解决方案1】:

这个循环将以x 等于-1 结束(假设x 已签名),但它的主体不会在最后一步产生对array[-1] 的访问。最后一个数组访问是array[0]。该行为在所有实现中都是一致的。

换句话说,您引用的代码中的负索引数组访问没有问题。但是如果你尝试在循环之后立即访问array[x],那么你确实会访问array[-1]

您引用的代码是一种相当知名的实现模式的变体,当需要使用 unsigned 变量作为索引对数组进行向后迭代时使用。例如

unsigned x;
int a[5];

for (x = 5; x-- > 0; )
  a[x] = 0;

有时,经验不足的程序员在对数组进行反向迭代时会遇到使用无符号索引的问题。 (由于无符号变量永远不会有负值,循环终止条件的幼稚实现为x >= 0 不起作用。)这种方法 - 即循环终止条件中的后增量 - 在这种情况下有效。 (当然,它也适用于有符号索引)。

【讨论】:

  • 我仍然觉得for (unsigned x = 5; x <= 5; x--) 更容易阅读。
  • @Jens Gustedt:首先,在这种情况下应该是for (unsigned x = 4; x <= 4; ...。其次,您的情况背后的逻辑并不是很明显(是的,我知道它是如何工作的,但是……)。我可能更喜欢for (unsigned x = 4; x != -1; x--),尽管对于没有准备的读者来说,unsigned 变量与-1 的比较也可能看起来令人困惑。最后一个变体的美妙之处在于它也适用于有符号类型。
  • 4 而不是5 的权利。所以你看到原始版本真的让一些人感到困惑:) x != -1 对我来说没问题,但我仍然认为 x <= 4 是一个完美的表达方式,它准确地捕捉了 unsigned 值的范围。
【解决方案2】:

如果x的初始值为5,则执行:

array[4] = NULL;
array[3] = NULL;
array[2] = NULL;
array[1] = NULL;
array[0] = NULL;

如果x是有符号类型,那么x的最终值为-1;否则为该类型的最大值。

【讨论】:

    【解决方案3】:

    在处理while 循环(前提条件)之前,确保x 为非负数。 当进程离开while 循环(后置条件)时,x 的值也将为 -1。因此,离开while循环后,您不应该使用x作为索引访问array

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-08
      • 1970-01-01
      • 2012-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多