我正在读卡内基梅隆幻灯片上的电脑系统,为我的测验。在幻灯片第49页中:
使用无符号进行计数 正确使用无符号作为循环索引的方法 无符号i;for (i = cnt-2;i< cnt;i--) ai += ai+1; 更好 size_t i;for (i = cnt-2;i< cnt;i-) ai += ai+1;
我不明白为什么它不是无限循环。我正在减少i,并且它没有签名,所以它应该总是小于cnt。请解释一下。
发布于 2017-02-26 06:11:37
这似乎是用于实现相同事物的既定成语的另一种表达方式。
for (unsigned i = N; i != -1; --i)
...;他们只是简单地将i != -1的可读性更强的条件替换为稍微更神秘的i < cnt。当0在unsigned域中减少时,它实际上封装为UINT_MAX值,该值等于-1 (在无符号域中),并且大于或等于cnt。因此,i != -1或i < cnt都是继续迭代的条件。
他们为什么要这样做呢?显然,因为它们是从cnt - 2开始的,而且cnt的值可能小于2,在这种情况下,它们的状态确实正常工作(而i != -1没有)。除了这种情况之外,没有理由让cnt参与终止条件。人们可能会说,更好的方法是预先检查cnt的值,然后使用i != -1成语。
if (cnt >= 2)
for (unsigned i = cnt - 2; i != -1; --i)
...;注意,BTW,只要i的起始值是非负的,基于i != -1条件的实现就可以工作,而不管i是有符号的还是无符号的。
发布于 2017-02-26 06:06:52
这个循环仅仅依赖于i将减少超过0的事实,这使得它成为最大值uint值。这会中断循环,因为现在是i < cnt == false。
无符号数字不会溢出,而是使用模块化的属性进行包装。
C和C++标准都保证了这种uint包装行为,但对于有符号整数却没有定义。
发布于 2022-03-15 07:38:49
到目前为止,我发现下行计数循环的最佳选择是使用
for(unsigned i=N; i-->0; ) { }这用i=N-1 . 0调用循环体。对于签名数据类型和无符号数据类型,这种方法都是相同的,并且不依赖于任何溢出。
https://stackoverflow.com/questions/42465263
复制相似问题