使用无符号字符循环

7
如果必须使用无符号字符类型的变量 i,那么在不进入无限循环的情况下执行类似操作的优雅方式是什么?
for (unsigned char i = 0; i < 256; ++i) {
    printf("%d\n", i); 
}   
3个回答

18
unsigned char i = 0;
do {
    printf("%u\n",i);
}while(++i != 0);

在循环测试中进行递增并针对包装值进行测试。


编译器能展开它吗? - Phil H

3
作为一个经验法则:如果你的迭代器变量需要保存0和"Uxxx_MAX"之间的所有值,那么你选择的算法类型就太狭窄了。你应该考虑使用uint16_t代替。
有很多情况下你无法使用一个大的整数类型来代替你的无符号字符变量。所以我问你,你的应用程序是为一个8位MCU编写的实时嵌入式系统吗?你发现这个循环是性能瓶颈吗?
  • 如果是,那么请使用uint8_t作为迭代器类型来写一个晦涩难懂的循环,并注释说明为什么这样做。
  • 如果不是,那么请使用uint16_t或更大的整数类型。

0
将检查放在主体之后、增量之前。
for (unsigned char i = 0; ; ++i) {
    printf("%d\n", i); 
    if(i==255)
        break;
}   

但是你也可以用 while:
unsigned char i = 0;
while( ) {
    printf("%d\n", i); 
    if(i==255)
        break;
    ++i;
}   

甚至可以将检查推开:

for (unsigned char i = 0; i++ < 255; ) {
    printf("%d\n", i); 
}   

所有这些在增量之前都会检查255,而不是之后检查零,因此,如果变量是CHAR或某个当前限制为256但可以更改的宏,则这些仍将起作用,因为它们不依赖于溢出。将int替换其中,它仍然有效。

1
所有这些例子都相当晦涩,我不会使用也不建议使用它们。 - Lundin
@Lundin:仅依赖于溢出也是不明确的,而且并没有明确显示迭代次数。我甚至怀疑编译器是否能展开循环,即使它是静态长度的? - Phil H
确实,依赖溢出是不明确的,尽管它是有明确定义的。我想我会自己写一个答案... :) - Lundin
@PhilH:你的第一个例子是正确的,但是 while( ) 有一个错别字:我需要像 while(true) 这样的条件。 你的第三个例子不正确,因为它循环了255次,而不是 OP 想要循环256次。 - Remz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接