Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 常量字符的strlen是否已优化?_C_String_Optimization_Strlen - Fatal编程技术网

C 常量字符的strlen是否已优化?

C 常量字符的strlen是否已优化?,c,string,optimization,strlen,C,String,Optimization,Strlen,我可以在这样的循环中使用const char*的strlen,并期望O(n)时间复杂度,还是会导致O(n^2)?我认为它看起来比使用字符串长度变量更简洁 void send_str( const char* data ) { for (uint8_t i = 0; i < strlen(data); i++) send_byte( data[i] ); } void send_str(常量字符*数据){ 对于(uint8_t i=0;i。不优化不考虑函数(甚至库)

我可以在这样的循环中使用
const char*
strlen
,并期望O(n)时间复杂度,还是会导致O(n^2)?我认为它看起来比使用字符串长度变量更简洁

void send_str( const char* data ) {
    for (uint8_t i = 0; i < strlen(data); i++)
        send_byte( data[i] );
}
void send_str(常量字符*数据){
对于(uint8_t i=0;i

这取决于优化级别吗?

我认为你永远无法依赖优化的发生

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

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()
,自己检测字符串的结尾。

编译器可能会优化它,但可能不会达到您希望的程度。显然,这取决于编译器版本和优化级别

你可以考虑使用它来理解GCC对你的代码做了什么(例如,内部GIMPLE表示是由编译器转换成的)。或者

gcc-fverbose asm-O-S
来获取生成的汇编代码

但是,对于您的示例,编写以下代码更简单:

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

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

例如,
send\u 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-因此这不是编译器要进行的合法转换。

即使strlen没有,编译器也应该对其进行优化。strlen(数据)是一个操作,将在每个循环中执行,最好使用一个变量来存储一次值并使用,因为如果使用GCC和Clang测试did soI,方法调用将发生一次;在每个回合中都调用<代码>斯特林< /代码>。不优化不考虑函数(甚至库)。是的,这实际上是XY问题…1用于关注OP的实际需求。在本例中,发送4个元素而不是1是否会改变性能?例如,检查地址是否可以被4整除,然后从4乘4开始,在发送之前查看数据的内容(如果有空的话)?另外,如果地址不能被4整除,先缓慢地执行1-3个元素,然后继续执行4乘4?-1,
send\u byte()
只通过值传递一个字符,它不能修改任何内容。@unwind:
send\u byte()
可以通过全局变量访问同一对象。