Как мне преобразовать оператор IF с 2 переменными в функцию switch с помощью C?

У меня есть оператор 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!");}

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

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

Ответы на вопрос(7)

#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

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

 Keine Lust04 янв. 2013 г., 22:13
@StephenCanon уверен :)#define CASE(a, b) } else if ((a == _a) && (b == _b)) { _a != a ? 0
 Stephen Canon04 янв. 2013 г., 18:53
Это действительно красиво в ужасающем виде.
 Keine Lust04 янв. 2013 г., 22:24
jajaja, да, см. редактировать
 Stephen Canon04 янв. 2013 г., 22:18
@DavidRF: это не такне работает, если первое выражение после: является назначением (т.е.CASE(a,b): x = 2; действительно неразобрать так, как вы хотели бы). (Это также выигралработать хорошо, если_a бывает с плавающей точкой NaN). Я думаю, вам нужно создать фиктивный ярлык, чтобы он действительно работал должным образом. Наверное просто{ dummylabel ## __LINE__ или похожие.
 Tiago C.04 янв. 2013 г., 20:18
хахахах очень хороший человек! я
 Stephen Canon04 янв. 2013 г., 21:53
будет еще больше впечатлен, если вы злоупотребите препроцессором, чтобы: после .CASE(a,b)

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

switch ((play1 < 8) + play2) {

  case 'RP':

    printf ("Paper wins!");
    break;

  case 'RS':

    printf ("Rock wins!");
    break;

  case 'RR':

    printf ("Draw!");
    break;
 }

Вы можете вкладывать свои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;
  ...
}

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

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

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");
}

поскольку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

В общем, ответ "нет ":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
}
 effeffe04 янв. 2013 г., 17:00
Тот'+1 ужасно, +1!
 Jack04 янв. 2013 г., 17:38
Спасибо. Но я предпочитаю если-еще если ..
 user52975804 янв. 2013 г., 17:00
@dasblinkenlight Проблема не в форматировании :)
 axiom04 янв. 2013 г., 17:00
Является ли вложенный переключатель хорошей идеей?
 user52975804 янв. 2013 г., 16:58
Уч. Чем дольше я снимаюсь в этом фильме, тем больше у меня запинается разум.
 dasblinkenlight04 янв. 2013 г., 17:03
@axiom Да: вложенный переключатель легко превзойдет эту конструкцию по удобочитаемости, и его производительность, вероятно, будет примерно такой же. Хотя это будет дольше.
 dasblinkenlight04 янв. 2013 г., 17:00
@ H2CO3 Я исправил форматирование, но сомневаюсь, что из-за этого было бы намного проще смотреть на это :)
 Alberto Bonsanto04 янв. 2013 г., 17:03
Я люблю эту идею!
#include 
#include 

#define PAIR(X,Y) (X
 MOHAMED04 янв. 2013 г., 21:20
@ Как хорошо, я понял. Я обновил ответ. я использовалX+(Y
 Howard04 янв. 2013 г., 17:42
Будьте осторожны с приоритетом оператора. Вы'Я буду использовать.play1 + (play2

Ваш ответ на вопрос