循环所有值

Loop over ALL the values

本文关键字:循环      更新时间:2023-10-16

这可能是一个奇怪的问题,但如何很好地循环一个类型的所有值。特别是标准积分类型,例如CCD_。一个普通的for循环构造带来了一个困难:使用什么条件退出循环——因为所有值都是有效的。

当然,有几种方法可以完成这项工作。在最后一个值上退出,然后在循环后处理它。使用较大的int进行计数。问题是,还有更优雅的方式吗?

如果你想要一个漂亮的解决方案,你可以这样做:

for(auto x : everyvalue<short>()) {
  std::cout << x << 'n';
}

其中everyvalue为:

#include <limits>
template<typename T>
struct everyvalue {
  struct iter {
    T x;
    bool flag;
    inline iter operator++() {
      if(x == std::numeric_limits<T>::max())
        flag = true;
      else
        ++x;
      return *this;
    }
    inline T operator*() { return x;}
    inline bool operator!=(iter& i) {return flag != i.flag;}
    // note: missing some iterator requirements, still should work
  };
  inline iter begin() { return iter{std::numeric_limits<T>::min(),0}; }
  inline iter end() { return iter{std::numeric_limits<T>::max(),1}; }
};

否则,将优选简单的CCD_ 4。

我曾经担心过同样的问题,这是我能想到的最好的:

unsigned char c = 0;
do
{
    printf("%d ", (int)c); //or whatever
} while (++c != 0);

这是我发现do..while语法非常有用的少数几种情况之一。

请注意,从技术上讲,它只对无符号类型有效,因为我依赖于值的包装。

#include <limits>
int i = std::numeric_limits<int>::min();
do {
    ...
    if(i == std::numeric_limits<int>::max())
        break;
    i++;
} while(true);

这与翻译为:的for()语句形成对比

#include <limits>
int i = std::numeric_limits<int>::min();
while(true) {
    if(i == std::numeric_limits<int>::max())
        break;
    ...
    i++;
};

您可以将递增的值与一个标志组合起来,表示您已经达到最大值,这样您就不会递增超过它:

for ( char i ( std::numeric_limits<char>::min() ), j ( 1 );
      i != std::numeric_limits<char>::max() || j--;
      i += j )
    std::cout << ( int ) i << 'n';

但只有"精致"而非"简洁简洁的线条"中的优雅。

查找最小值和最大值?

您可以使用更大的类型:

unsigned long i;
for (i = std::numeric_limits<unsigned short>::min();
     i <= std::numeric_limits<unsigned short>::max();
     i++)

我最近问了一个关于布尔的相同问题:如何在布尔值(false和true)上编写"for"循环。你可以在那里寻找答案。然后我意识到,由于对所有可能的值进行迭代的for循环需要再次评估条件,因此您需要一个额外的值(任何形式的值-更大的类型、第二个变量等)来正确区分所有情况。而且,do while循环适用于这种情况,因为它需要与不同值一样多的比较。