Вопрос по switch-statement, variables, if-statement, c – Как мне преобразовать оператор IF с 2 переменными в функцию switch с помощью C?

0

У меня есть оператор IF, который я хочу преобразовать в оператор Switch ... Но он имеет 2 переменные! Возможно ли это сделать на С?

Это игра камень, ножницы, бумага:

(R для камня, P для бумаги, S для ножниц)

     char play1, play2;

     printf("\nPlayer 1 - Enter your Play: ");
     scanf ("%c", &play1);
     printf("\nPlayer 2 - Enter your Play: ");
     scanf (" %c", &play2); 


     if (play1 == 'R' && play2 == 'P') {
       printf ("Paper wins!"); }
      else if (play1 == 'R' && play2 == 'S') {
        printf ("Rock wins!");}
      else if (play1 == 'R' && play2 == 'R) {
        printf ("Draw!");}

и я должен сделать это для других вариантов, так что было бы лучше использовать переключатель!

Пожалуйста, покажите нам свой код. SLaks
это возможно, если ваши переменные могут быть объединены в одну. Вроде как C ++ мультиплексор. Если возможные значенияsupervariable» Четко диктовать состояния исходных двух переменных, тогда это возможно. примеры: конкатенация строк, битовая маскировка и т. д. im so confused
1. Почему вы хотите это сделать? 2. Разместите фактическое if-утверждение в вопросе. Stephen Canon
мы добавили мой код! Tiago C.

Ваш Ответ

7   ответов
0

посколькуswitch работает с одной переменной, выЯ должен каким-то образом объединить несколько входов в одно значение. Учитывая числовые значения для символов ASCII 'R', 'P'и 'S'добавление двух символов вместе даст вам уникальную сумму для каждой пары. Тем не менее, результирующий код, вероятно, будет более трудным для чтения, чем эквивалентныйif дерево. В общем, это обычно неЭто хороший вариант, потому что ваш код очень легко сломается, когдадобавлены новые параметры ввода и основные предположения для вашего "сочетание» операция (например, уникальная сумма) больше не удерживается.switch также становится громоздким, так как количество возможных входных значений увеличивается. Так как вам нуженcase для каждой возможной комбинации вашswitch станет большим и сложным в обслуживании, если использовать что-либо большее, чем несколько вариантов ввода.

switch блок на самом деле приведет к большему количеству кода, чем при использованииif для этого конкретного случая. С помощьюif дает вам возможность обрабатывать несколько случаев одновременно. Например, вы неНужны три отдельные версии кода, который проверяет связь. Вы также можете использовать таблицу для поиска ответов вместоswitch или жеif, Вот'Вот пример, который объединяет эти подходы:

// Table of outcomes.  The option in the second
// column wins over the option in the first column.
char matchup[3][2] = {
  {'P', 'S'}, // paper is cut and destroyed
  {'S', 'R'}, // scissors are smashed and destroyed
  {'R', 'P'}, // rock is ... covered up?
};

void announce_winner(char player1, char player2)
{
  int i;

  if (player1 == player2) {
    printf("Draw\n");
    return;
  }

  for (i=0; i<3; ++i) {
    if (player1 == matchup[i][0])
      printf("%c wins\n", (player2 == matchup[i][1]) ? player2 : player1);
  }
}

Большим преимуществом табличного подхода является то, что ваш код отделен от ваших данных. Если правила игры меняются или кто-то изучает игру и хочет узнать, кто в какой ситуации выигрывает, таблица становится намного более удобной для пользователя, чем копание большого количества кода.switch Блок - это, по сути, таблица поиска и код обработки, все смешанные вместе, и для сложных случаев это становится ужасно быстрым.

0

Слишком умное решение в два раза:

enum Play { Rock = 0, Paper = 1, Scissors = 2 };
enum Outcome { Tie = 0, P1Win = 1, P2Win = 2 };

enum Play parseMove(char input) {
    switch (input) {
        case 'R': return Rock;
        case 'P': return Paper;
        case 'S': return Scissors;
        default: /* invalid input */;
    }
}

enum Outcome gameResult(enum Play p1, enum Play p2) {
    return (3 + p1 - p2)%3;
}

...

switch(gameResult(parseMove(play1), parseMove(play2))) {
    case Tie: printf("Tie!\n");
    case P1Win: printf("Player 1 wins!\n");
    case P2Win: printf("Player 2 wins!\n");
}
9
#include 

#define SWITCH(a, b) char _a = a; char _b = b; if (0)
#define CASE(a, b) } else if ((a == _a) && (b == _b)) {

int main(void)
{
    char play1, play2;

    printf("\nPlayer 1 - Enter your Play:");
    scanf ("%c", &play1);
    getchar();
    printf("\nPlayer 2 - Enter your Play:");
    scanf ("%c", &play2);
    getchar();

    SWITCH(play1, play2) {
        CASE('R','P') printf ("Paper wins!");
        CASE('R','S') printf ("Rock wins!");
        CASE('R','R') printf ("Draw!");
    }
    return 0;
}

Это'шутка: P

РЕДАКТИРОВАТЬ: поддержка случая ":"

#define PASTE(a, b) a##b
#define LABEL(a, b) PASTE(a, b)
#define SWITCH(a, b) char _a = a; char _b = b; if (0)
#define CASE(a, b) } else if ((a == _a) && (b == _b)) { LABEL(LBL, __LINE__)

Но неработать с:

CASE('R','R'): printf ("Draw a!"); CASE('S','R'): printf ("Draw!");

Два случая в одной строке

Решено с помощью:

#define SWITCH(a, b) char _a = a; char _b = b; if (0)
#define CASE(a, b) } else if ((a == _a) && (b == _b)) {switch(1) case 1

Надеюсь, никто не использует это :)

хахахах очень хороший человек! я Tiago C.
будет еще больше впечатлен, если вы злоупотребите препроцессором, чтобы: после .CASE(a,b) Stephen Canon
@DavidRF: это не такне работает, если первое выражение после: является назначением (т.е.CASE(a,b): x = 2; действительно неразобрать так, как вы хотели бы). (Это также выигралработать хорошо, если_a бывает с плавающей точкой NaN). Я думаю, вам нужно создать фиктивный ярлык, чтобы он действительно работал должным образом. Наверное просто{ dummylabel ## __LINE__ или похожие. Stephen Canon
Это действительно красиво в ужасающем виде. Stephen Canon
0

Вы можете вкладывать своиswitch операторы для каждого выражения, такие как

switch(a)
{
  case 'A':
    switch(b)
    {
      case 0: // do something with A0
        break;
      case 1: // do something with A1
        break;
      ...
    }
    break;

  case 'B':
    switch(b)
    {
      case 0: // do something with B0
        break;
      ...
    }
    break;
  ...
}

Как вы можете видеть, это может очень быстро стать очень уродливым. Если вам нужно переходить на основе комбинаций значений, то вы 'вероятно, лучше сохранить текущую структуру.

6

В общем, ответ "нет ":switch операторы работают с одной переменной. Однако в некоторых случаях вы можете сделать преобразование. Например, если у вас есть две переменные,a а такжеb, гдеa может быть 0, 1 или 2, иb это может быть0, 1, 2, or 3Вы можете сделать переключение следующим образом:

switch (a*10+b) {
    case  0: break; // a == 0, b == 0
    case 10: break; // a == 1, b == 0
    case 20: break; // a == 2, b == 0
    case  1: break; // a == 0, b == 1
    case 11: break; // a == 1, b == 1
    case 21: break; // a == 2, b == 1
    case  2: break; // a == 0, b == 2
    case 12: break; // a == 1, b == 2
    case 22: break; // a == 2, b == 2
    case  3: break; // a == 0, b == 3
    case 13: break; // a == 1, b == 3
    case 23: break; // a == 2, b == 3
}
Является ли вложенный переключатель хорошей идеей? axiom
Спасибо. Но я предпочитаю если-еще если .. Jack
@dasblinkenlight Проблема не в форматировании :) user529758
Тот'+1 ужасно, +1! effeffe
1

Я бы порекомендовал многосимвольные символьные константы для достижения этого кратким образом:

switch ((play1 << 8) + play2) {

  case 'RP':

    printf ("Paper wins!");
    break;

  case 'RS':

    printf ("Rock wins!");
    break;

  case 'RR':

    printf ("Draw!");
    break;
 }
2
#include 
#include 

#define PAIR(X,Y) (X<<8)|Y

int main()
{
    char play1, play2;

    printf("\nPlayer 1 - Enter your Play: ");
    scanf ("%c", &play1);
    printf("\nPlayer 2 - Enter your play: ");
    scanf (" %c", &play2); 

    switch (PAIR(play1, play2)) {
        case PAIR('R','P'):
            printf ("Paper wins!\n");
            break;
        case PAIR('R','S'):
            printf ("Rock wins!\n");
            break;
        case PAIR('R','R'):
            printf ("Draw!\n");
            break;
        default: //any thing else
            printf ("Default!\n");
            break;
    }
}
@ Как хорошо, я понял. Я обновил ответ. я использовалX+(Y MOHAMED
Будьте осторожны с приоритетом оператора. Вы'Я буду использовать.play1 + (play2 Howard

Похожие вопросы