2012-11-10 4 views
2

Моя программа вылетает из-за того, что она достигает stack.top(), она не должна достигать, поскольку стек пуст. у меня есть, если проверяющий только что:Weirdest C++ stack empty() fault

if(!st.empty()); 
     //do stuff 

(я инициализируется

stack<int> st; 

).

Но хотя я могу видеть в отладке, что стек пуст, он все равно идет в if! Я даже написал этот код:

if(st.size()>0); 
     cout<<st.size(); 

И он печатает 0! Что происходит и как я могу это исправить? Благодаря!

+0

«Моя программа» ... какая у вас программа? Как мы должны рассказывать, что происходит, если мы не увидим этого? – Mehrdad

ответ

17

с запятой после того, если заявления являются проблемой

BAD:

if(st.size()>0); // <-- this should not be here!!!!!!!! 
    cout<<st.size(); 

Правильно переписано:

if(st.size()>0) { 
    cout<<st.size(); 
} 

Кроме того, как @WhozCraig указал, другой оператор тоже имеет точку с запятой!

BAD:

if(!st.empty()); // <--BAD! 
    //do stuff 

Хорошо:

if(!st.empty()) { 
    //do stuff 
} 

ВСЕГДА !! используйте скобки с ветвями (если, переключатель) и петлями (для, пока, делать-пока) !!! Это окупает большое время! (Не говоря уже, милый котенок умирает каждый раз, когда такой блок записывается без скобок!) ВСЕГДА !!

Например, это может убить день в отладке:

BAD:

int i=0; 
... 
while(i++<1000); 
    doStuff(i); 

Хорошо:

int i=0; 
... 
while(i++<1000) { 
    doStuff(i); 
} 

Остерегайтесь (как @WhozCraig указал снова) это не автомагически решить проблему с запятой прекращается ветви и петли заявления, так как это вполне допустимо синтаксис:

if (condition);{ ...code... } 

Или

if (condition); 
{ 
    ...code... 
} 

Но на мой взгляд и опыт (это полностью субъективная!) - поскольку я сам попал в эту ловушку пару раз - я испытал это, когда у меня появилась фигурная скобка после вышеупомянутых утверждений, я никогда не делал ошибку, набрав точку с запятой снова. Присоединение к этому соглашению было серебряной пулей - для меня, и другие могли воспользоваться этим. Кроме того, если бы там была точка с запятой, это бы сразу привлекло мое внимание, просто посмотрев, поскольку это «необычный образец символов» .

+0

+1 проблема на ** оба ** если утверждения btw (не ваш, оригинальный пост). – WhozCraig

+4

Fwiw, фигурные скобки не являются волшебной пулей для завершенных if-statements, while-statements или любой другой конструкции блока управления. 'if (condition); {... code ...}' столь же корректно (и так же разбито), как и без фигурных скобок, и в зависимости от формата выбора редактора, так же трудно обнаружить. – WhozCraig

+0

@WhozCraig, что определенно верно, но, как я сам попал в эту ловушку пару раз - я испытал это, когда у меня есть фигурная скобка после вышеупомянутых утверждений, я никогда не совершал ошибку, набрав точку с запятой слишком. Поэтому, придерживаясь этого соглашения, это была серебряная пуля - для меня ... Не попадала в ловушку с тех пор. Кроме того, если бы там была точка с запятой, это сразу же привлекло бы мое внимание, просто взглянув, поскольку это «необычный образец символов». (Я тоже включаю это в ответ, так как это определенно добавляет к нему) – ppeterka

8

Существует нет «КРП», как ваш, если содержит только пустое заявление:

if(!st.empty()); 
     //do stuff -- that's outside the if!!!! 

(фона:. Синтаксис является if (condition) block, с block быть либо заявление или блок операторов ; пустое заявление, так if (...) ; означает «если условие выполнено, то ничего не делать». - которые, вероятно, никогда, что вы имеете в виду)

вы должны написать

if(!st.empty()) { 
     //do stuff -- now it's inside! 
} 

Будьте осторожны! НЕ пишите

if(!st.empty()); // notice the semicolon making it wrong; without the semicolon it would be ok 
{ 
     // outside again 
} 
+1

Примечание: хорошие компиляторы должны поймать этот, при условии, что вы активируете правильные предупреждения, такие как '-Wempty-body' для Clang: * warning: if statement имеет пустой кузов [-Wempty-body] * , –