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

时间:2020-07-05 07:55:53

标签: c++ switch-statement

所以我是C ++的新手,我正在阅读一个pdf教程,它使我开始学习基本知识。我当时正在编写一个简单的案例程序,但感到有些奇怪。

#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.";
    }
}

每当我在“ if(feel == ok)”之后没有“ else”时,都不会调用默认大小写,并且如果我随机输入某些内容,它将得到eGood大小写的文本。我想知道为什么会这样,并且由于我正在学习C ++,所以我不想就把它清除掉,却不知道在我将else语句放进去之后它为什么能工作。因此,如果有人可以向我解释这一点,那就太好了!对不起,我的语法不好。

4 个答案:

答案 0 :(得分:3)

使用诸如g++ -Wall -Wextra -Werror之类的警告来编译程序,并且它甚至不会编译,因为string_feeling hashit(string const& feeling)并非在所有情况下都返回值。

在未启用警告的情况下编译代码是浪费时间的肯定方法。

答案 1 :(得分:2)

if函数中三个hashit语句中的条件均不成立时,该函数中不执行任何return语句,并且调用未定义行为

(引自N3337 6.6.3 return语句)

从函数末尾流出就等于没有值的返回;这会导致返回值函数的行为不确定。

为避免这种情况,您应该在enum

中再添加一种
enum string_feeling {
    eGood,
    eBad,
    eOk,
    eOther // add this
};

并在不满足任何条件时将其返回。

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
}

答案 2 :(得分:1)

您总是必须返回一个值,否则行为是不确定的

如果您无法修改枚举来添加某种未知感觉的情况,则可以修改 hashit 以在 feeling 有效的情况下返回true,并在这种情况下设置输出参数具有相应的枚举值,否则返回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;
      }
    }
}

编译和执行:

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 $ 

除此之外:

  • 命名您的枚举string_feeling并不十分清楚,无论将什么感觉输入为字符串,最好将其命名为 Feeling

  • hashit 中通过按值获取字符串以将其更改为小写,然后仅将其与“好”,“坏”和“确定”进行比较,或者使用strcasecmp的{​​{1}}上,还可以管理“ gOoD”等

答案 3 :(得分:0)

如果不满足if个条件,则hashit去了

else cout << "";

由于您没有显式编写return语句,因此该函数将返回默认值0,该值等于eGood

但是,默认返回值并不总是0。这是undefined behaviour

如果使用其他编译器运行此代码,则may会得到不同的结果。