在C中的for循环条件中调用strlen()的最佳替代方法是什么?

时间:2010-03-03 17:36:32

标签: c string for-loop

我已经读过在我的for循环条件中调用strlen()是不好的做法,因为这是一个O(N)操作。

但是,在查看备选方案时,我会看到两种可能的解决方案:

int len = strlen(somestring);  
for(int i = 0; i < len; i++)  
{

}

...或

for(int i = 0; somestring[i] != '\0'; i++)  
{

}

现在,第二个选项似乎可能具有以下优点:1)不声明不必要的变量,2)如果字符串长度在循环中被修改,它应该仍然到达结尾,只要长度不是&LT;岛

然而,我不确定。其中哪一个是C程序员的标准做法?

6 个答案:

答案 0 :(得分:9)

第二个通常是首选。

另一种流行的形式是

for (char* p = something; *p; p++)
{
   // ... work with *p
}

还有一个是

char* p = something;
char c;
while ((c = *p++))
{
    // ... do something with c
}

(需要额外的()左右分配才能使一些可疑的编译器不发出警告,说明我可能意味着在while条件内进行比较)

确实,strlen非常慢,因为它必须通过整个字符串寻找尾随0.因此,strlen基本上实现为

int s = 0;
while (*p++) s++;
return s;

(实际上,使用稍微更优化的汇编程序版本)。

因此,如果可能,您应该避免使用strlen

答案 1 :(得分:3)

这些是首选:

for (int i = 0; str[i]; ++i)
for (char* p = str; *p; ++p)

答案 2 :(得分:3)

如果循环的某些部分可以覆盖字符串末尾的NUL字符,那么调用strlen的版本仍然会在缓冲区结束之前完成。第二个版本可以超出缓冲区并聚集在别人的记忆中。 strlen版本一目了然也更容易理解。

答案 3 :(得分:1)

通常是第二个。如果没有别的,第一个必须遍历字符串两次:一次查找长度,再次操作每个元素。另一方面,如果您已经编写了代码strlen,则可能更容易将strlen调用提升出循环并仍然获得大多数的好处。

答案 4 :(得分:0)

第一种方法对我来说是这样的:

while(..) { Test end of string }  /* strlen */
while(..) { Your Code }           /* processing */

虽然第二种方法如下:

while(..) { Your Code + Test end of string } /* both */
恕我直言,这两种方法计算的操作数量大致相同,并且 我认为它们是等价的。另外,如上所述,strlen是quite optimized, 并经过充分测试。 而且,第二种方法看起来像是过早优化:) 你最好 如有必要,测试/分析您的代码然后进行优化(毕竟,它只是一个线性算法)。

然而,如果处理,您可以考虑第二种方法 可能会在字符串结束之前很久就停止(例如,找到一个单词的第一个出现)。

答案 5 :(得分:0)

正如其他答案所述,虽然两种选择都有效但第二种情况更常见。但是反对'\ 0'的比较字符不是我推荐的。 '\ 0'的类型是int,而不是char。也就是说,它与0具有相同的类型。但是,写入'\ 0'比仅仅0更容易出错,因为偶然的退格可以将其转换为'0',这根本不相同。偶然阅读代码的人可能不会轻易发现这个错误。