使用无符号索引在C中向后迭代数组

时间:2017-08-21 21:30:38

标签: c arrays loops unsigned

以下代码是否可以安全地向后迭代数组?

for (size_t s = array_size - 1; s != -1;  s--)
    array[s] = <do something>;

请注意,我将sunsigned)与-1进行比较;

有更好的方法吗?

3 个答案:

答案 0 :(得分:3)

这段代码非常棘手。如果我对C标准的阅读是正确的,那么如果size_t至少与int一样大,那么您的代码就是安全的。通常情况是这样的,因为size_t通常实现为unsigned long int

在这种情况下,-1会转换为size_ts的类型)。 -1不能用无符号类型表示,因此我们应用模运算将其置于范围内。这为我们提供了SIZE_MAX(类型size_t的最大可能值)。同样,s 0递减SIZE_MAX+1模式为SIZE_MAX,这也会导致s = 0。因此,在处理size_t情况后,您的循环将完全结束您希望结束的位置。

另一方面,如果unsigned short类似于int(且short大于int),那么size_t可能代表所有可能的s int 1}}值和(int)SIZE_MAX != -1将转换为false。换句话说,比较将以SIZE_MAX完成,它将始终返回<stdint.h>,从而破坏您的代码。但我从来没有见过可能发生这种情况的系统。

使用-1(由for (size_t s = array_size - 1; s != SIZE_MAX; s--) ... 提供)代替for (size_t s = array_size; s--; ) ... ,您可以避免任何潜在问题:

baseBean

但我最喜欢的解决方案是:

AnotherBean

答案 1 :(得分:0)

好吧,s永远不会是-1,所以你的结局条件永远不会发生。 s将从0变为SIZE_MAX,此时您的程序可能会因内存访问错误而出现段错误。更好的解决方案是从最大尺寸开始,并从您使用它的任何地方减去一个:

for (size_t s = array_size; s > 0; s--)
    array[s-1] = <do something>;

或者您可以将此功能组合到for循环的语法中:

for (size_t s = array_size; s--;)
    array[s] = <do something>;

在进入循环之前将减去一个,但在减去1之前检查s == 0

答案 2 :(得分:0)

迭代中的IMO使用足够大的有符号值。它更容易被人类阅读。