【问题标题】:for loop with switch statements [closed]带有switch语句的for循环[关闭]
【发布时间】:2016-01-25 01:53:03
【问题描述】:

我对 C/C++ 比较陌生,我想知道如何使用 for 循环,这样我就不必制作一堆 switch 语句 我已经制作了 switch 语句 我只需要集成 for 循环的帮助进去。谢谢。

#include <stdio.h>
#pragma warning(disable :   4996)   
int main()  {
    char    ch;
    ch = getchar();
    int f, a = 10, b = 20;
    printf("ch  =   %c\n", ch);


    switch (ch) {
    case '+':   f = a + b;  printf("f   =   %d\n", f); break;
    case '-':   f = a - b;  printf("f   =   %d\n", f); break;
    case '*':   f = a * b;  printf("f   =   %d\n", f); break;
    case '/':   f = a / b;  printf("f   =   %d\n", f); break;
    default:    printf("invalid operator\n");
    }

}

程序的目的是输入 +、-、*、/ 中的任何一个,然后根据该输入执行输入的情况,因此 + 将添加 a 并在一起。

【问题讨论】:

  • 评论中的“不使用中断”指的是什么?我至少可以看到一次休息,
  • 这段代码的目的是什么?你能提供一个输入和预期的输出吗?
  • 当只执行一种情况时,for 循环在你的计算器程序中有什么用处?
  • 你可以有一组运算符和一组函数指针,循环并比较,然后调用适当的函数;)
  • @DaniEne 您应该编辑掉“不使用中断”注释,而不是编辑掉 break 语句!

标签: c++ c for-loop switch-statement


【解决方案1】:

基本上,您需要将运算符字符映射到操作。

您当前的代码表示通过执行流控制进行的映射。

在 C++ 中,标准库的 map 集合是一个不错的选择,可以将其表示为数据,因此您甚至不需要使用循环。在 C 中,每个包含 char 和函数指针的结构数组可以完成相同的工作。但是,您必须自己定义函数,因为与 C++ 标准库不同,C 标准库没有为算术运算提供方便的命名函数。


以类似的方式,布尔状态,无论是真还是假,都可以表示为执行位置或数据,通常表示为bool 类型的变量。选择什么主要是工程直觉。有时通过流控制表示最简单、最清晰,有时作为数据表示最简单、最清晰。


C++ 示例,主要重现给定示例代码的效果,但映射为数据:

#include <iostream>
#include <functional>
#include <map>
using namespace std;

auto main() -> int
{
    const map<char, function<int(int,int)>> op =
    {
        { '+', plus<int>() },
        { '-', minus<int>() },
        { '*', multiplies<int>() },
        { '/', divides<int>() }
    };

    char  ch;
    cout << "Operator? ";  cin >> ch;
    cout << "ch = '" << ch << "'\n";

    if( op.count( ch ) == 0 )
    {
        cout << "invalid operator\n";
    }
    else
    {
        const int a = 10;
        const int b = 20;
        cout << "f   =   " << op.at( ch )( a, b ) << "\n";
    }
}

对应的 C 示例,其中确实包含问题中提到的 for 循环:

#include <stdio.h>

int plus( int a, int b )        { return a+b; }
int minus( int a, int b )       { return a-b; }
int multiplies( int a, int b )  { return a*b; }
int divides( int a, int b )     { return a/b; }

typedef int(*Func_ptr)(int, int);

struct Mapping
{
    char        ch;
    Func_ptr    f;
};

const struct Mapping op[] =
{
    { '+', plus },
    { '-', minus },
    { '*', multiplies },
    { '/', divides }
};

const int n_ops = sizeof( op )/sizeof( *op );

Func_ptr op_at( char ch )
{
    for( int i = 0; i < n_ops; ++i )
    {
        if( op[i].ch == ch ) { return op[i].f; }
    }
    return NULL;
}

int main()
{

    int  ch;        // Note: type `int` to accommodate EOF value.
    printf( "Operator? " );  ch = getchar();
    printf( "ch = '%c'\n", ch );

    if( op_at( ch ) == NULL )
    {
        printf( "invalid operator\n" );
    }
    else
    {
        const int a = 10;
        const int b = 20;
        printf( "f   =   %d\n", op_at( ch )( a, b ) );
    }
}

我认为是 C11 引入了一些机制来有效地重载函数,因此它们可以像 C++ 中的重载函数一样使用。我不记得太多,也没有在这里使用它。我建议如果您需要处理不同的数据类型,只需使用不同的函数名称即可。


请注意,C 示例也可以编译为 C++,因此这两个示例在技术上都是 C++。但是,最后一个示例是 C 风格的,使用 C 习惯用法和 C i/o,并且做了 C++ 中不必要的事情。我们通常只是说这样的代码是 C,而不是 C 风格;这样的代码可能并不总是作为 C++ 编译,因为虽然 C 在很大程度上是 C++ 的一个子集,但它们是两种不同的独立语言:技术上没有 C/C++ 这样的东西。

【讨论】:

  • 这是“如果您不想要 C++ 答案,请不要使用 C 和 C++ 双重标记”中的对象课程。
  • @JonathanLeffler:感谢您的编辑和关于标签的注释。我没有注意到双语。那么也将创建一个 C 示例。
【解决方案2】:

我想知道如何使用 for 循环,这样我就不必制作一堆 switch 语句我已经制作了 switch 语句我只需要帮助将 for 循环集成到其中。

for 循环用于重复语句块,直到满足条件。

switch 语句用于根据给定值决定运行哪个语句块,而不是使用一堆 if 语句。

for 循环替换 switch 语句是没有意义的。有意义的是使用switch 语句inside of 循环,对循环生成的内容采取行动,例如要求用户输入。例如:

#include <stdio.h>

#pragma warning(disable :   4996)   

int main()  {
    int f, a = 10, b = 20;
    char ch;
    int finished = 0;

    do {
        ch = getchar();
        printf("ch  =   %c\n", ch);

        switch (ch) {
            case '+':   f = a + b;  printf("f   =   %d\n", f); break;
            case '-':   f = a - b;  printf("f   =   %d\n", f); break;
            case '*':   f = a * b;  printf("f   =   %d\n", f); break;
            case '/':   f = a / b;  printf("f   =   %d\n", f); break;
            case 'q':   finished = 1; break;
            default:    printf("invalid operator\n"); break;
        }
    }
    while (!finished);

    return 0;
}

【讨论】: