以下代码是否可以安全地向后迭代数组?
for (size_t s = array_size - 1; s != -1; s--)
array[s] = <do something>;
请注意,我将s
(unsigned
)与-1
进行比较;
有更好的方法吗?
答案 0 :(得分:3)
这段代码非常棘手。如果我对C标准的阅读是正确的,那么如果size_t
至少与int
一样大,那么您的代码就是安全的。通常情况是这样的,因为size_t
通常实现为unsigned long int
。
在这种情况下,-1
会转换为size_t
(s
的类型)。 -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使用足够大的有符号值。它更容易被人类阅读。