【问题标题】:Looping with an unsigned char使用无符号字符循环
【发布时间】:2012-10-19 19:54:35
【问题描述】:

如果i 必须是unsigned char,那么在不进入无限循环的情况下执行类似操作的优雅方法是什么?

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

【问题讨论】:

    标签: c loops


    【解决方案1】:
    unsigned char i = 0;
    do {
        printf("%u\n",i);
    }while(++i != 0);
    

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

    【讨论】:

    • 编译器可以展开这个吗?
    【解决方案2】:

    作为一般经验法则:如果您的迭代器变量需要保存 0 到“Uxxx_MAX”之间的所有值,那么您为算法选择了一个太窄的类型。

    您应该考虑改用uint16_t

    在很多情况下,您不能使用大的 int 类型而不是 unsigned char。那么让我问你,你的应用程序是为 8 位 MCU 编写的实时嵌入式系统,你发现这个循环本身就是性能瓶颈吗?

    • 如果是,则使用uint8_t 作为迭代器的类型编写一个晦涩的循环,并说明您这样做的原因。
    • 如果不是,则使用uint16_t 或更大的整数类型。

    【讨论】:

      【解决方案3】:

      将检查放在正文之后和增量之前

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

      但是你不妨再做一会儿:

      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,它仍然有效。

      【讨论】:

      • 所有这些例子都很晦涩,我不会使用也不推荐任何一个。
      • @Lundin:依赖溢出也是晦涩难懂的,并没有明确显示迭代次数。我什至想知道编译器是否可以展开循环,即使它是静态长度的?
      • 确实,依赖溢出是晦涩难懂的,尽管它是明确定义的。我想我会自己写一个答案... :)
      猜你喜欢
      • 2021-10-04
      • 1970-01-01
      • 2019-03-22
      • 1970-01-01
      • 2012-10-06
      • 1970-01-01
      • 2020-03-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多