我可以在这样的循环中使用strlen
的{{1}}并期望O(n)时间复杂度,还是会导致O(n ^ 2)?我认为它看起来比使用变量作为字符串长度更清晰。
const char*
是否取决于优化级别?
答案 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 - 所以这不会是编译器的合法转换。