這可能是一個奇怪的問題,但是如何很好地循環一個類型的所有值。特別是標準積分類型,如unsigned short
。正常的for
循環結構呈現一個難點:用什麼條件來退出循環 - 因爲所有的值都是有效的。循環遍歷所有值
當然,有幾種方法可以完成工作。退出最後一個值,然後在循環後處理。使用更大的int來計數。問題是,有沒有更優雅的方式?
這可能是一個奇怪的問題,但是如何很好地循環一個類型的所有值。特別是標準積分類型,如unsigned short
。正常的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}; }
};
否則簡單break
將是首選。
我要給這個答案一個大綠色的勾號。最終結果是優雅和廣泛的。所有醜陋的東西都是一次完成,完成並隱藏起來,這是如何使用C++的重要組成部分(在我看來)。其他一些答案可能會有性能優勢,但這並不是我之前的做法。 – wxffles 2012-02-01 20:46:33
我建議您再次閱讀該問題。這與其他(現在刪除的)答案有相同的問題。 – quasiverse 2012-01-31 23:15:33
你可以只用一個更大的類型:
unsigned long i;
for (i = std::numeric_limits<unsigned short>::min();
i <= std::numeric_limits<unsigned short>::max();
i++)
'我<= i!= [']'?那只是爲了'我<= [']'? – quasiverse 2012-01-31 23:16:17
是 - 複製/粘貼錯誤!固定。 – 2012-01-31 23:17:02
+1當然,假設'unsigned long'確實比'unsigned short'大。這是我知道的實現,但我只是指出它不能保證。 – 2012-01-31 23:17:44
#include <limits>
int i = std::numeric_limits<int>::min();
do {
...
if(i == std::numeric_limits<int>::max())
break;
i++;
} while(true);
這是相反的,轉化爲爲()語句:
#include <limits>
int i = std::numeric_limits<int>::min();
while(true) {
if(i == std::numeric_limits<int>::max())
break;
...
i++;
};
我不downvoting,但有符號整數溢出是未定義的行爲。 (有關有符號整數溢出出錯的示例,請參閱http://stackoverflow.com/q/7682477) – 2012-01-31 23:19:37
編輯出來並不是什麼大問題 – 2012-01-31 23:20:56
我擔心關於這個同樣的問題一次,這是我能想到的最好的:
unsigned char c = 0;
do
{
printf("%d ", (int)c); //or whatever
} while (++c != 0);
我發現do..while
語法很有用的極少數情況之一。
請注意,從技術上講,它只對無符號類型有效,因爲我依賴於值的包裝。
我最近問了一個關於bools的問題:How to write a `for` loop over bool values (false and true)。你可以在那裏尋找答案。然後我意識到,因爲for循環遍歷所有可能的值需要再次評估條件,所以需要額外的值(以任何形式 - 更大類型,第二個變量等)來正確區分所有情況。而且,do-while循環適用於這種情況,因爲它需要完全一樣多的比較,因爲有不同的值。
你可以通過你用標誌遞增值結合起來,說你已經達到最大,所以你不增加過去吧:
for (char i (std::numeric_limits<char>::min()), j (1);
i != std::numeric_limits<char>::max() || j--;
i += j)
std::cout << (int) i << '\n';
但只有優雅如「複雜」,而不是'乾淨簡單的線條'。
聽起來像你試圖蠻力的東西?不要嘗試使用64位整數,儘管... – Mysticial 2012-01-31 23:12:44