C++ for(char&;c:s)和for(char c:s)之间的区别是什么?

C++ for(char&;c:s)和for(char c:s)之间的区别是什么?,c++,C++,这是leetcode上的一个问题 给定一个只包含字符“(”、“)”、“{”、“}”、“[”和“]”的字符串,确定输入字符串是否有效 括号必须按正确的顺序闭合,“()”和“()[{}”都有效,但“(]”和“([)]”无效 这是一个解决方案: class Solution { public: bool isValid(string s) { stack<char> paren; for (char& c : s) {

这是leetcode上的一个问题

给定一个只包含字符“(”、“)”、“{”、“}”、“[”和“]”的字符串,确定输入字符串是否有效

括号必须按正确的顺序闭合,“()”和“()[{}”都有效,但“(]”和“([)]”无效

这是一个解决方案:

class Solution {
public:
    bool isValid(string s) {
        stack<char> paren;
        for (char& c : s) {
            switch (c) {
                case '(': 
                case '{': 
                case '[': paren.push(c); break;
                case ')': if (paren.empty() || paren.top()!='(') return false; else paren.pop(); break;
                case '}': if (paren.empty() || paren.top()!='{') return false; else paren.pop(); break;
                case ']': if (paren.empty() || paren.top()!='[') return false; else paren.pop(); break;
                default: ; // pass
            }
        }
        return paren.empty() ;
    }
};
class Solution {
public:
    bool isValid(string s) {
        stack<char> paren;
        for (char c : s) {
            switch (c) {
                case '(': 
                case '{': 
                case '[': paren.push(c); break;
                case ')': if (paren.empty() || paren.top()!='(') return false; else paren.pop(); break;
                case '}': if (paren.empty() || paren.top()!='{') return false; else paren.pop(); break;
                case ']': if (paren.empty() || paren.top()!='[') return false; else paren.pop(); break;
                default: ; // pass
            }
        }
        return paren.empty() ;
    }
};
在第一个解决方案中

for (char c : s) 
在第二种解决方案中。 然而,第一种解决方案只需要3毫秒,第二种解决方案需要6毫秒。 那么为什么第一种解决方案比第二种解决方案快呢

for (char c : s) 
这将在
s
中创建每个元素的副本,并将其存储在
c
中。这意味着修改
c
不会修改
s

for (char& c : s) 
这不会在
s
中创建每个元素的副本,而是直接引用并将其作为别名存储在
c
中。这意味着修改
c
会修改
s

for (char& c : s) 

由于复制可能是一项昂贵的操作,因此它的性能比引用慢(即使在不存在优化的情况下使用内置类型),从而避免了复制

如果要防止无意中修改字符串,则可以使用
const
引用,即:

for (const char& c : s) 

记得启用优化吗?一个类似于函数的参数
void foo(char&);
,另一个类似于
foo(char);
可能通过常量引用获取函数参数(即
bool isValid(string const&s)
)因此,避免复制会给您带来更多的加速。另一个加速的方法是为堆栈保留内存(与输入字符串的内存相同),避免在
push()
中重新分配。您可能会认为任何级别的优化都应该避免复制这个简单的代码,还是不?“与参考相比,它的性能更慢",这并不总是正确的,尤其是对于内置类型。谢谢!我对编码是新手,我发现我有很多东西要学!@songyuanyao,这可能很大程度上取决于优化水平,不是吗?@Walter是的,当然,在进行性能测量之前。但是作为我从有效的C++是“”。