在给定的循环中,例如:
for(int i=0 ; i < strlen(s) ; i++){
//do something
}
是否为循环的每次迭代计算了strlen? C和C ++语言如何处理这个问题?如果要对每次迭代进行此函数调用,并且我们事先知道函数的结果将是常量,那么将此值存储在变量中是否更有效?例如:
int length = strlen(s);
for(int i=0 ; i< length ; i++){
//do something
}
答案 0 :(得分:3)
是,每次迭代都会评估strlen(s)
。
如果您不在循环中更改字符串,则将值存储在更好(更快)中,然后将其包含在for循环中。
最快的方法是:
for(int i=0, length = strlen(s) ; i< length ; i++){
//do something
}
答案 1 :(得分:2)
是否为循环的每次迭代计算了strlen?
是
将此值存储在变量中是否更有效?
是。在每次迭代及其堆栈维护上调用函数会导致一些额外的开销。
答案 2 :(得分:0)
在C ++ 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];}
};
这是一个简单的小班。一些助手:
template<class T>
array_view<T> view(T* b,T* e){return {b,e};}
template<class T>
array_view<T> view(T* b,std::size_t l){return {b,b+l};}
template<class T, unsigned N>
array_view<T> view(T(&a)[N]){return view(&a[0],N};}
template<class T, unsigned N>
array_view<T> view(std::array<T,N>& a){return view(&a[0],N};}
template<class T, unsigned N>
array_view<const T> view(std::array<T,N>const& a){return view(&a[0],N};}
template<class T, class...Xs>
array_view<T> view(std::vector<T,Xs...>& v){return view(v.data(),v.size()};}
template<class T, class...Xs>
array_view<const T> view(std::basic_string<T,Xs...>const & v){return view(v.data(),v.size()};}
template<class T, class...Xs>
array_view<T> view(std::vector<T,Xs...>& v){return view(v.data(),v.size()};}
template<class T, class...Xs>
array_view<const T> view(std::basic_string<T,Xs...>const & v){return view(v.data(),v.size()};}
最后:
array_view<char> view(char*str){return view(str, strlen(str));}
array_view<char const> view(char const*str){return view(str, strlen(str));}
现在我们可以这样做:
for(char& c:view(str)){
// code
}
如果需要,可以通过&c-str
获取索引。
还有一种更有效的方法:使用sentinals和指向索引,以避免在结束之前计算长度。