简体   繁体   English

为什么这个case语句需要一个“if else”而不仅仅是一个“if”?

[英]Why does this case statement need an “if else” and not just an “if”?

So I am new to C++, and I am working through a pdf tutorial that is getting me started with basic stuff.所以我是 C++ 的新手,我正在学习 pdf 教程,该教程让我开始学习基本知识。 I was writing a simple case program, and I experienced something weird.我正在编写一个简单的案例程序,我遇到了一些奇怪的事情。

#include "pch.h"
#include <iostream>
#include <string>

using namespace std;

enum string_feeling {
    eGood,
    eBad,
    eOk,
};

string_feeling hashit(string const& feeling) {
    if (feeling == "Good" || feeling == "good" || feeling == "GOOD") {
    return eGood;
    }
    if (feeling == "Bad" || feeling == "bad" || feeling == "BAD") {
        return eBad;
    }
    if (feeling == "Ok" || feeling == "ok" || feeling == "OK") {
        return eOk;
    } 
    else cout << "";
}

int main() {
    string username;
    cout << "Hello! Please enter your first name here: \n";
    cin >> username;
    cout << "Hello, " << username << "!\n";
    cout << "How are you today? ";
    string feeling;
    cin >> feeling;
    cout << endl;

    switch (hashit(feeling)) {
    case eGood:
        cout << "That's great!";
        break;
    case eBad:
        cout << "I hope you are happy soon!";
        break;
    case eOk:
        cout << "That's good.";
        break;
    default:
        cout << "Ok.";
    }
}

Whenever I didn't have the "else" after the "if (feeling == ok)" stuff, the default case would never be called and if I entered something random it would give me the text from the eGood case.每当我在“if (feeling == ok)”之后没有“else”时,将永远不会调用默认案例,如果我输入随机的内容,它会给我 eGood 案例中的文本。 I was wondering why this is happening and since I'm learning C++ I didn't want to just brush it off not ever knowing why it worked after I put the else statement in there.我想知道为什么会发生这种情况,因为我正在学习 C++ 我不想只是刷掉它,不知道为什么在我把 else 语句放在那里之后它会起作用。 So, if anyone could explain this to me that would be great.因此,如果有人可以向我解释这一点,那就太好了。 Sorry for my bad grammar.对不起我的语法不好。

Compile your program with warnings enabled like g++ -Wall -Wextra -Werror and it won't even compile, because string_feeling hashit(string const& feeling) does not return a value in all cases.在启用警告的情况下编译您的程序,例如g++ -Wall -Wextra -Werror它甚至不会编译,因为string_feeling hashit(string const& feeling)在所有情况下都不会返回值。

Compiling code without warnings enabled is a surefire way to waste time.在不启用警告的情况下编译代码是一种浪费时间的可靠方法。

When none of conditions in the three if statements in hashit function become true, no return statement is executed in the function and undefined behavior is invoked.hashit function 中的三个if语句中的任何一个条件都不为真时,在 function 中不执行return语句并调用未定义的行为

(Quote from N3337 6.6.3 The return statement) (引自N3337 6.6.3 返回语句)

Flowing off the end of a function is equivalent to a return with no value;从 function 的末端流出相当于没有值的返回; this results in undefined behavior in a value-returning function.这会在返回值的 function 中导致未定义的行为。

To avoid this, you should add one more kind to the enum为避免这种情况,您应该向enum添加一种

enum string_feeling {
    eGood,
    eBad,
    eOk,
    eOther // add this
};

and return it when no conditions are met.不满足条件时返回。

string_feeling hashit(string const& feeling) {
    if (feeling == "Good" || feeling == "good" || feeling == "GOOD") {
    return eGood;
    }
    if (feeling == "Bad" || feeling == "bad" || feeling == "BAD") {
        return eBad;
    }
    if (feeling == "Ok" || feeling == "ok" || feeling == "OK") {
        return eOk;
    } 
    else cout << "";
    return eOther; // add this
}

You always have to return a value else the behavior is undefined您总是必须返回一个值,否则行为未定义

If you cannot modify your enum to add a case for an unknown feeling you can modify hashit to return true if feeling is valid and in that case to set the output parameter with the corresponding enum value, else to return false without setting the output parameter:如果您无法修改枚举以添加未知感觉的案例,您可以修改hashit以在感觉有效时返回 true,在这种情况下,使用相应的枚举值设置 output 参数,否则在不设置 output 参数的情况下返回 false:

#include <iostream>
#include <string>

using namespace std;

enum string_feeling {
    eGood,
    eBad,
    eOk,
};

bool hashit(string const& feeling, string_feeling & r) {
  if (feeling == "Good" || feeling == "good" || feeling == "GOOD") {
    r = eGood;
  }
  else if (feeling == "Bad" || feeling == "bad" || feeling == "BAD") {
    r = eBad;
  }
  else if (feeling == "Ok" || feeling == "ok" || feeling == "OK") {
    r = eOk;
  } 
  else
    return false;
  
  return true;
}

int main() {
    string username;
    cout << "Hello! Please enter your first name here: \n";
    cin >> username;
    cout << "Hello, " << username << "!\n";
    cout << "How are you today? ";
    string feeling;
    cin >> feeling;
    cout << endl;
    
    string_feeling f;
    
    if (! hashit(feeling, f))
      cout << "I do not understand how you are" << endl;
    else {
      switch (f) {
      case eGood:
        cout << "That's great!" << endl;
        break;
      case eBad:
        cout << "I hope you are happy soon!" << endl;
        break;
      case eOk:
        cout << "That's good." << endl;
        break;
      }
    }
}

Compilation and execution:编译和执行:

pi@raspberrypi:/tmp $ g++ -Wall c.cc
pi@raspberrypi:/tmp $ ./a.out
Hello! Please enter your first name here: 
bruno
Hello, bruno!
How are you today? good

That's great!
pi@raspberrypi:/tmp $ ./a.out
Hello! Please enter your first name here: 
bruno
Hello, bruno!
How are you today? aze

I do not understand how you are
pi@raspberrypi:/tmp $ 

Out of that:其中:

  • to name your enum string_feeling is not very clear, whatever the feeling was input as a string, better to just name it Feeling命名你的枚举string_feeling不是很清楚,无论输入为字符串的感觉,最好只命名为Feeling

  • it can be practical in hashit to get the string by value to change it to lowercase then to just compare it with with "good" "bad" and "ok" or to use strcasecmp on its .c_str() , allowing to also manage "gOoD" etchashit中按值获取字符串以将其更改为小写然后将其与“好”“坏”和“好”进行比较或在其.c_str()上使用strcasecmp是可行的,还允许管理“好”等

If no if conditions will meet, hashit went to if条件不满足, hashit

else cout << "";

Since you didn't explicitly write the return statement, the function returns the default value 0 , which is equal to eGood .由于您没有明确编写return语句,因此 function 返回默认值0 ,等于eGood

However, the default return value is not always 0 .但是,默认返回值并不总是0 This is an undefined behaviour .这是undefined behaviour

If you runs this code with a different compiler, you may get different results.如果您使用不同的编译器运行此代码,您may得到不同的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM