“array [n]!='\ 0'”是否比“n< strlen(array)”更好?

时间:2015-10-29 02:25:50

标签: c++

对于

char array [10];
cin.getline(array, 10);

哪一个是最佳选择?

for(int n = 0; array[n] != '\0'; n++) {...}

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

2 个答案:

答案 0 :(得分:6)

第二种方法非常差,因为strlen()每次调用时都必须扫描整个数组,以搜索0字节。

您可以在循环前调用strlen一次来改善它:

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

除了for循环完成的扫描外,还需要扫描一次数组。

某些编译器可能能够检测到数组在循环期间没有发生变化,因此他们可以将您的strlen()版本优化为第二个版本。但我认为依靠它是一个好主意。

但是直接检查元素可以避免任何额外的扫描,因此效率最高。任何其他方法都不可能比这更好地进行优化。

答案 1 :(得分: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数据结构。这是个好建议。要使用名为std::array的{​​{1}}或std::vector,请将第一个示例的前两行替换为a。要使用名为const size_t buf_size = a.size();的{​​{1}},请将第二个示例的前三行替换为std::string