對於「array [n]!=' 0'」比「n <strlen(array)」更好嗎?
char array [10];
cin.getline(array, 10);
其中哪些是最好的選擇?
for(int n = 0; array[n] != '\0'; n++) {...}
或
for(int n = 0; n < strlen(array); n++) {...}
對於「array [n]!=' 0'」比「n <strlen(array)」更好嗎?
char array [10];
cin.getline(array, 10);
其中哪些是最好的選擇?
for(int n = 0; array[n] != '\0'; n++) {...}
或
for(int n = 0; n < strlen(array); n++) {...}
第二種方法是非常差的,因爲strlen()
必須掃描整個數組每次你怎麼稱呼它,時間來搜索0
字節。
您可以通過循環之前曾經呼籲strlen
提高了一點:
size_t len = strlen(array);
for (int n = 0; n < len; n++) { ... }
這需要掃描該陣列一次,除了由for
循環中完成掃描。
有些編譯器可能能夠檢測到陣列在循環過程中沒有改變,所以他們可以優化你的strlen()
版本到第二個版本。但我不認爲依靠它是一個好主意。
但是,直接檢查元素可以避免任何額外的掃描,所以它是最有效的。其他任何方法都不可能比這更好地優化。
現代編譯器執行此優化(舊的編譯器可能也會這樣做) –
掃描數組一次而不是兩次通常效率更高,因此幾乎所有的時候都應該使用第一種方法。在大多數現實世界的情況下,您也應該檢查緩衝區溢出,所以你會寫東西喜歡的方式:
// This only works for arrays, not pointers! With pointers, buffer size is a parameter.
constexpr size_t buf_size = sizeof(array)/sizeof(array[0]);
for (size_t i = 0; i < buf_size && array[i]; ++i)
do_stuff_with(array[i]);
或者:
// This only works for arrays, not pointers!
constexpr size_t buf_size = sizeof(array)/sizeof(array[0]);
const size_t m = strnlen_s(array, buf_size);
for (size_t i = 0; i < m; ++i)
do_stuff_with(array[i]);
你可能想使用第二個主要的原因的方法是,無論如何您都需要查找字符串的長度,例如爲深度複製分配內存或在循環內執行子字符串匹配。在這種情況下,僅查找一次長度會更有效,您也可以在循環條件中使用它。
有幾條評論建議使用STL數據結構。這是很好的建議。要使用名爲a
的std::array
或std::vector
,請將第一個示例的前兩行替換爲const size_t buf_size = a.size();
。要使用名爲s
的std::string
,請將第二個示例的前三行替換爲const size_t m = s.size();
。
如果您使用C++ 11,則可以使用知道其大小的std :: array。 –
,並且在任何C++版本中都有'std :: string',它也知道它的大小,並且不需要多次掃描字符串 –
爲什麼在第一個中會出現'&& array [i]'? – EmmanuelMess
爲什麼不使用std :: string? –
@Nir Friedman這只是關於數組的一個通用問題,相反它可能是一個int數組。 – EmmanuelMess
人們不會終止int數組,所以我不明白這是如何合理適用於int數組。 –