奇怪的C++堆栈空()错误

nod*_*dwj 2 c++ stl

我的程序崩溃,因为它到达stack.top()它不应该到达,因为堆栈是空的.我有一个if检查那个:

    if(!st.empty());
        //do stuff
Run Code Online (Sandbox Code Playgroud)

(我已经初始化了

stack<int> st;
Run Code Online (Sandbox Code Playgroud)

).

但是虽然我可以在调试中看到堆栈是空的,它仍然在if!我甚至写了这段代码:

    if(st.size()>0);
        cout<<st.size();
Run Code Online (Sandbox Code Playgroud)

它打印0!发生了什么,我该如何解决?谢谢!

ppe*_*rka 17

if语句后面的分号是问题所在

坏:

if(st.size()>0); // <-- this should not be here!!!!!!!!
    cout<<st.size();
Run Code Online (Sandbox Code Playgroud)

正确改写:

if(st.size()>0) {
    cout<<st.size();
}
Run Code Online (Sandbox Code Playgroud)

另外,正如@WhozCraig指出的那样,另一个语句也有分号!

坏:

if(!st.empty()); // <--BAD!
    //do stuff
Run Code Online (Sandbox Code Playgroud)

好:

if(!st.empty()) {
    //do stuff
}
Run Code Online (Sandbox Code Playgroud)

总是!!使用括号分支(if,switch)和循环(for,while,do-while)!它回报很大!(更不用说,一个可爱的小猫每次都会死掉这样一个没有括号的块!)总是!!

例如,这可以在调试中消耗一天:

坏:

int i=0;
...
while(i++<1000);
    doStuff(i);
Run Code Online (Sandbox Code Playgroud)

好:

int i=0;
...
while(i++<1000) {
    doStuff(i);
}
Run Code Online (Sandbox Code Playgroud)

注意(正如@WhozCraig再次指出的那样)这不会自动解决分号终止的分支和循环语句的问题,因为这是完全有效的语法:

if (condition);{ ...code... } 
Run Code Online (Sandbox Code Playgroud)

要么

if (condition);
{ 
     ...code... 
} 
Run Code Online (Sandbox Code Playgroud)

在我看来和经验(这是完全主观的!) - 因为我自己已陷入这个陷阱几次 - 我经历过,当我在上述陈述之后有大括号时,我从未犯过错误再次输入分号.坚持这个惯例是一个银弹 - 对我来说,其他人也可以从中受益.此外,如果那里有分号,它会立即引起我的注意,只是通过观察,因为它是一种"不常见的人物模式".

  • 对于终止的if语句,while语句或任何其他块控制构造,Fwiw,花括号不是魔术子弹.`if(condition); {... code ...}`和没有大括号一样有效(也就像破坏一样),并且取决于编辑器的格式选择,同样难以发现. (4认同)

Joh*_*hnB 8

没有"在if中",因为你的if只包含一个空语句:

if(!st.empty());
        //do stuff -- that's outside the if!!!!
Run Code Online (Sandbox Code Playgroud)

(背景:语法是if (condition) block,用block.无论是一个语句或语句块;是一个空语句,所以if (...) ;意思是"如果当时条件满足什么都不做" -这可能永远是你的想法.)

你应该写

if(!st.empty()) {
        //do stuff -- now it's inside!
}
Run Code Online (Sandbox Code Playgroud)

小心!不要写

if(!st.empty()); // notice the semicolon making it wrong; without the semicolon it would be ok
{
        // outside again
}
Run Code Online (Sandbox Code Playgroud)