【问题标题】:C++ | How Do I Loop an If Statement Without Returning a Value Each TimeC++ |如何循环一个 if 语句而不每次都返回一个值
【发布时间】:2017-07-20 04:03:25
【问题描述】:

我在一个函数中有一个循环,它通过一个数组递增,检查每个元素是否与函数的参数匹配。

我的问题是返回值的要求。由于返回一个值完成了函数,如果一个错误的匹配返回 false 并且我需要在每个控制路径上返回一个值,那么我将无法检查数组中的任何其他元素以查看它们是否匹配。

我的大部分经验是在 AS3 中,这种功能结构确实有效。我将如何在 C++ 中正确地构造这个函数?

功能:目的是检查输入的命令是否存在,如果为真或假则返回布尔值

bool Commands(string _input)
{
    string cmds[] = { "login", "logout", "exit" };

    int i = 0;
    do {
        if (_input == cmds[i])
        {
            return true;
        }
        else
        {
            if (i == sizeof(cmds))
            {
                return false;
            }
        }
        i++;
    } while (i < sizeof(cmds));
}

【问题讨论】:

  • sizeof(cmds) 并没有按照你的想法去做。
  • return std::find(std::begin(cmds), std::end(cmds), _input) != std::end(cmds); ?
  • 这样的函数返回一个布尔值并没有什么意义——你的程序几乎肯定需要类似的代码来计算出哪些命令被输入了,所以你不妨返回一个int - 值i,并说-1 表示无效命令;那么您可以在switch 语句中使用int 值。稍加努力,您就可以创建一个enum,其中包含每个命令的值和一个无效的哨兵。也就是说,在调用者中直接使用if (input == "login") ... else if (input == "logout") ... else // invalid ...; 通常是最好的。

标签: c++ function loops boolean return-value


【解决方案1】:

对于初学者来说,最好将参数声明为常量引用。 无需声明std::string 类型的对象数组。声明一个字符串字面量数组要好得多。

循环错误。例如,这个表达式 sizeof(cmds) 在类似这样的条件下没有意义

 if (i == sizeof(cmds))

数组元素个数的计算方式如下

sizeof(cmds) / sizeof( *cmds)

使用标准算法可以大大简化函数。

随便写

#include <iostream>
#include <iomanip>
#include <string>
#include <algorithm>
#include <iterator>

bool Commands( const std::string &s )
{
    const char * cmds[] = { "login", "logout", "exit" };

    return std::find( std::begin( cmds ), std::end( cmds ), s ) != std::end( cmds );
}

int main() 
{
    std::cout << std::boolalpha << Commands( "logout" ) << std::endl;
    std::cout << std::boolalpha << Commands( "hello" ) << std::endl;

    return 0;
}

程序输出是

true
false

如果你想在函数中使用循环,那么它可以如下所示

#include <iostream>
#include <iomanip>
#include <string>

bool Commands( const std::string &s )
{
    const char * cmds[] = { "login", "logout", "exit" };
    const size_t N = sizeof( cmds ) / sizeof( *cmds );

    size_t i = 0;

    while ( i < N && s != cmds[i] ) i++;

    return i != N;
}

int main() 
{
    std::cout << std::boolalpha << Commands( "logout" ) << std::endl;
    std::cout << std::boolalpha << Commands( "hello" ) << std::endl;

    return 0;
}

当一个简单的函数有多个出口并且在大多数情况下没有必要时,这不是一种好的编程风格。

【讨论】:

    【解决方案2】:

    我会建议一些改进:

    sizeof(cmds) 返回cmds 的大小以字节为单位,这将是sizeof(string) * 3,例如在 64 位系统上为 96;您的循环将在数组末尾运行,导致未定义的行为。一种选择是使用sizeof(cmds)/sizeof(*cmds) 来获取元素的数量,但出于您的目的,使用带有初始化列表的std::vector 会更简单:

    std::vector<string> cmds { "login", "logout", "exit" };
    

    接下来,您可以将do 循环替换为for 循环,并将sizeof 替换为std::vector.size() 成员函数。如果输入不匹配,您只需不要return 并继续循环的下一次迭代。如果循环后函数没有返回,则说明没有找到项目,可以return false

    for (size_t i = 0; i < cmds.size(); ++i)
      if (_input == cmds[i])
        return true;
    return false;
    

    您还可以用标准&lt;algorithm&gt; 标头中的std::find 算法调用替换循环:

    return std::find(std::begin(cmds), std::end(cmds), _input) != std::end(cmds);
    

    【讨论】:

    • 这里首选std::array
    • 感谢您的提示。我进行了您建议的更改。
    【解决方案3】:

    在循环时,当你找到你正在寻找的值时返回true。否则,当循环完成时,您可以在循环后简单地返回false

    bool Commands(string _input) {
        string cmds[] = { "login", "logout", "exit" };
    
        int i = 0;
        do {
            if (_input == cmds[i]) {
                return true; // we found it!
            }
            i++;
        } while (i < sizeof(cmds));
        return false; // we didn't find it.
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-09
      • 2014-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-23
      • 1970-01-01
      相关资源
      最近更新 更多