C++ 环路条件的计算

C++ 环路条件的计算,c++,c,design-principles,C++,C,Design Principles,在给定的循环中,例如: for(int i=0 ; i < strlen(s) ; i++){ //do something } for(int i=0;i

在给定的循环中,例如:

for(int i=0 ; i < strlen(s) ; i++){
    //do something
}
for(int i=0;i
是否为循环的每次迭代计算strlen?C语言和C++语言如何处理这个问题?如果每次迭代都要调用这个函数,并且我们事先知道函数的结果是常量,那么将这个值存储在变量中是否更有效?例如:

int length = strlen(s);
for(int i=0 ; i< length ; i++){
    //do something
}
int-length=strlen(s);
for(int i=0;i
strlen
将在每次迭代中进行评估

如果不在循环中更改字符串,则最好(更快)将值存储在中,然后将其包含在for循环中

最快的方法是:

for(int i=0, length = strlen(s) ; i< length ; i++){
    //do something
}
for(int i=0,length=strlen;i
strlen
将在每次迭代中进行评估

如果不在循环中更改字符串,则最好(更快)将值存储在中,然后将其包含在for循环中

最快的方法是:

for(int i=0, length = strlen(s) ; i< length ; i++){
    //do something
}
for(int i=0,length=strlen;i
是否为循环的每次迭代计算strlen

将此值存储在变量中是否更有效

对。在每次迭代中调用函数及其堆栈维护会导致一些额外的开销

是否为循环的每次迭代计算strlen

将此值存储在变量中是否更有效

对。在每次迭代中调用函数及其堆栈维护会导致一些额外的开销< P>:

template<class T>
struct array_view {
  T*b=nullptr;
  T*e=nullptr;
  T*begin()const{return b;}
  T*end()const{return e;}
  std::size_t size()const{return e-b;}
  bool empty()const{return size()==0;}
  T&operator[](std::size_t i)const{return b[i];}
};
如果需要,可以通过
&c-str
获取索引

有一种更有效的方法:使用前哨和指针来避免在结束之前计算长度。C++中的

< P> 11:

template<class T>
struct array_view {
  T*b=nullptr;
  T*e=nullptr;
  T*begin()const{return b;}
  T*end()const{return e;}
  std::size_t size()const{return e-b;}
  bool empty()const{return size()==0;}
  T&operator[](std::size_t i)const{return b[i];}
};
如果需要,可以通过
&c-str
获取索引


还有一种更有效的方法:使用sentinal和指向索引的指针,以避免在到达终点之前计算长度。

Yes。是的。对此外,请注意,许多编译器(包括gcc)可以通过缓存strlen的结果来优化代码。但是,依赖于此不是一个好的实践。如果“函数的结果将是常量”是因为您在常量字符串上运行此循环,则可以省略整个
strlen
,并用常量值替换它。(只是要指出“这取决于”…)@Jongware一些编译器优化了
strlen
文本。是的。是的。对此外,请注意,许多编译器(包括gcc)可以通过缓存strlen的结果来优化代码。但是,依赖于此不是一个好的实践。如果“函数的结果将是常量”是因为您在常量字符串上运行此循环,则可以省略整个
strlen
,并用常量值替换它。(只是要指出“这取决于”…)@Jongware一些编译器优化了
strlen
的文本。“最快”。。。如果检查终止0,则根本不需要
strlen
。差别有多大
strlen
检查每个字符一次,因此,如果您自己做了,它将是相同的-除了函数调用之外。@jong我的意思是,只计算strlen一次比每次迭代计算strlen快。“最快”。。。如果检查终止0,则根本不需要
strlen
。差别有多大
strlen
检查每个字符一次,因此如果您自己检查,结果将是一样的-除了函数调用之外。@Jong我的意思是,只计算strlen一次比每次迭代计算strlen快。
for(char& c:view(str)){
  // code
}