const char的strlen是否已优化?

时间:2013-07-09 10:10:30

标签: c string optimization strlen

我可以在这样的循环中使用strlen的{​​{1}}并期望O(n)时间复杂度,还是会导致O(n ^ 2)?我认为它看起来比使用变量作为字符串长度更清晰。

const char*

是否取决于优化级别?

3 个答案:

答案 0 :(得分:16)

我认为你不能依赖进行优化。

为什么不这样做,如果你真的想避免额外的变量:

void send_str(const char *data)
{
  for(size_t i = strlen(data); i != 0; --i)
    send_byte(*data++);
}

或者,不那么愚蠢,更像是一个实际的生产质量C程序:

void send_str(const char *data)
{
  while(*data != '\0')
    send_byte(*data++);
}

在迭代两次字符时没有任何意义,所以不要再调用strlen(),自己检测字符串结尾。

答案 1 :(得分:0)

编译器可能会对此进行优化,但可能不会达到您想要的程度。显然取决于编译器版本和优化级别。

您可以考虑使用MELT probe来理解GCC对您的代码所做的事情(例如,编译器将其转换为内部Gimple表示)。或者gcc -fverbose-asm -O -S获取生成的汇编代码。

但是,对于您的示例,编码更简单:

 void send_str(const char*data) {
    for (const char*p = data; *p != 0; p++)
        send_byte(*p);
 }

答案 2 :(得分:0)

如果编译此代码时send_byte()的定义不可用(例如,它在另一个翻译单元中),则可能不能以您描述的方式进行优化。这是因为const char *指针不能保证指向的对象确实是const,因此send_byte()函数可以合法地修改它(send_byte()可以访问该对象通过全局变量)。

例如,send_byte()定义如下:

int count;
char str[10];

void send_byte(char c)
{
    if (c == 'X')
        str[2] = 0;
    count++;
}

我们调用了提供的send_str()函数,如下所示:

count = 0;
strcpy(str, "AXAXAX");
send_str(str);

然后count中的结果必须为2.如果编译器将strlen()中的send_str()调用挂出循环,那么它将改为6 - 所以这不会是编译器的合法转换。