2015-10-29 38 views
1

對於「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++) {...} 
+0

爲什麼不使用std :: string? –

+0

@Nir Friedman這只是關於數組的一個通用問題,相反它可能是一個int數組。 – EmmanuelMess

+0

人們不會終止int數組,所以我不明白這是如何合理適用於int數組。 –

回答

6

第二種方法是非常差的,因爲strlen()必須掃描整個數組每次你怎麼稱呼它,時間來搜索0字節。

您可以通過循環之前曾經呼籲strlen提高了一點:

size_t len = strlen(array); 
for (int n = 0; n < len; n++) { ... } 

這需要掃描該陣列一次,除了由for循環中完成掃描。

有些編譯器可能能夠檢測到陣列在循環過程中沒有改變,所以他們可以優化你的strlen()版本到第二個版本。但我不認爲依靠它是一個好主意。

但是,直接檢查元素可以避免任何額外的掃描,所以它是最有效的。其他任何方法都不可能比這更好地優化。

+0

現代編譯器執行此優化(舊的編譯器可能也會這樣做) –

0

掃描數組一次而不是兩次通常效率更高,因此幾乎所有的時候都應該使用第一種方法。在大多數現實世界的情況下,您也應該檢查緩衝區溢出,所以你會寫東西喜歡的方式:

// 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數據結構。這是很好的建議。要使用名爲astd::arraystd::vector,請將第一個示例的前兩行替換爲const size_t buf_size = a.size();。要使用名爲sstd::string,請將第二個示例的前三行替換爲const size_t m = s.size();

+0

如果您使用C++ 11,則可以使用知道其大小的std :: array。 –

+0

,並且在任何C++版本中都有'std :: string',它也知道它的大小,並且不需要多次掃描字符串 –

+0

爲什麼在第一個中會出現'&& array [i]'? – EmmanuelMess

相關問題