Switch и String

Тема в разделе "Arduino & Shields", создана пользователем alexxx86, 25 мар 2014.

  1. alexxx86

    alexxx86 Гик

    Добрый день!
    Подскажите пожалуйста возможноли использовать оператор switch с объектом String?
     
  2. Tomasina

    Tomasina Сушитель лампочек Модератор

    switch работает только с целочисленными значениями, извратиться с преобразованием можно, но проще и компактнее использовать if/else
     
  3. Airbus

    Airbus Радиохулиган Модератор

    Можно например так http://tinyurl.com/omw62xm как в последнем примере если if/else заменить на switch(case) А что конкретно интересует?
     
  4. Megakoteyka

    Megakoteyka Оракул Модератор

    Нельзя. Только целочисленные значения.
    Попробуйте скомпилировать этот код:
    Код (Text):
    void setup()
    {
    }

    void loop()
    {
      String str = "a";

      switch(str)
      {
        case "a":
          break;
        case "b":
          break;
      }
    }
    и убедитесь.

    Чтобы не строить "лесенку" из if .. else можно делать так:
    Код (Text):
    void SomeHandler(String str)
    {
      if(str.compareTo("a"))
      {
        ...
        return;
      }
      if(str.compareTo("b"))
      {
        ...
        return;
      }
      ...
      if(str.compareTo("z"))
      {
        ...
        return;
      }
    }
    Для оптимизации такого кода по времени выполнения нужно самое часто выполняемое условие ставить первым, второе по частоте использования вторым, ..., самое редко выполняющееся - последним.
     
    Последнее редактирование: 25 мар 2014
  5. geher

    geher Гуру

    На самом деле иногда бывает удобно использовать для работы со строками switch.
    Естественно, об использовании в case всей строки речи идти не может. Но обработать несколько первых символов команды, чтобы потом разделаться с параметрами - без проблем.

    Например, имеем набор команд, в которых первый символ определяет команду, второй - ее режим, а потом идут параметры.
    Конструкция получается примерно такая:
    Код (Text):
    String str;
    // Тут эта строка откуда-то берет значение (последовательный порт, радиомодуль...)
    ....
    // Тут обработка команд
    switch(Str[1])
    {
        case 'A':
            Serial.println("Command A");
            switch(Str[2])
            {
                  case 'M':
                        Serial.println("Command mode M for command A");
                        // Обработка параметров команды А режим М и выполнение команды
                        ..........
                        break;
                 case ....
                 .......
                  default:
                        Serial.println("Unknown command mode for command A");
            }
            break;
        case .....
        .......
        default:
            Serial.println("Unknown command");
    }
     
     
  6. Megakoteyka

    Megakoteyka Оракул Модератор

    Можно и так. Но важно понимать, что один символ, который в этом случае подставляется в switch - это та же самая целочисленная переменная типа char. А символ 'A' для компилятора ни что иное, как его численное представление. Символы - просто абстракция для удобства программиста, компилятор все равно оперирует числами.
     
  7. alexxx86

    alexxx86 Гик

    Какая жаркая тут дискуссия))))
    Хотел по синезубу отпровлять на ардуино некоторые каманды, для удобства хотел их сделать в виде, так сказать слов. Но такие заморочки не стоят этого поэтому команды организую в виде цифр.
    Спасибо всем за помощь!
     
  8. Megakoteyka

    Megakoteyka Оракул Модератор

    В текстовом виде обычно передают в тех случаях, когда требуется возможность чтения и/или редактирования данных человеком. Логи удобно вести. В ином случае удобней передавать коды команд - меньше памяти, меньше кода, меньше тактов. Вы приняли верное решение :)
     
    alexxx86 нравится это.
  9. awarm

    awarm Нуб

  10. Jedi Kriks

    Jedi Kriks Нерд

    Это быдлокод называется. Так хочется свич на стрингах юзать, что абсолютно противоречит определению строки в ООП мире, так пишите на JS, а не на плюсах.
     
  11. Megakoteyka

    Megakoteyka Оракул Модератор

  12. Unixon

    Unixon Оракул Модератор

    С помощью хэшей.
     
  13. Unixon

    Unixon Оракул Модератор

    ОК, подкину ка я сюда немного халвы... :D
    Код (Text):

    #include <stdint.h>

    typedef uint8_t data_t;
    typedef uint32_t hash_t;

    hash_t sdbm_hash(const data_t *data, const size_t size)
    {
    hash_t h = 0;
    //data_t c;
    for (size_t i = 0; i < size; i++)
    {
      h -= (h<<6) + (h<<16) +data[i];
    }
    return h;
    }
     
    ТС, дальше сами сообразите?
     
  14. thesatellite

    thesatellite Нерд

    Господа, имеется DTMF декодер и вот такой мною написанный скетч.
    • Подскажите плж как применить switch к такому раскладу? И реально ли?

      void setup()
      {
      pinMode(2, INPUT);
      pinMode(3, INPUT);
      pinMode(4, INPUT);
      pinMode(5, INPUT);
      pinMode(6, INPUT);
      pinMode(7, OUTPUT);
      pinMode(8, OUTPUT);
      pinMode(9, OUTPUT);
      pinMode(10, OUTPUT);
      }

      void loop()
      {
      boolean Q1 = digitalRead(2);
      boolean Q2 = digitalRead(3);
      boolean Q3 = digitalRead(4);
      boolean Q4 = digitalRead(5);
      boolean Q5 = digitalRead(6);

      if(Q1 && !Q2 && Q5)
      {
      digitalWrite(7, LOW);
      }
      if(!Q1 && Q2 && Q5)
      {
      digitalWrite(8, LOW);
      }
      if(Q1 && Q2 && !Q3 && Q5)
      {
      digitalWrite(9, LOW);
      }

      else
      {
      {
      digitalWrite(7, HIGH);
      digitalWrite(8, HIGH);
      digitalWrite(9, HIGH);
      }
      }
      }
     
  15. mcureenab

    mcureenab Гуру

    Q4 не используется?
     
  16. thesatellite

    thesatellite Нерд

    Доброй ночи. Используется. dtmf декодер mt8870 Q1 Q2 Q3 Q4 и STQ. Я решил BOLEAN использовать.
     
  17. mcureenab

    mcureenab Гуру

    Из Q1, Q2, Q3, Q5 можно собрать число от 0 до 15. По этому числу сделать switch.
    Но если в if вы просто опускаете переменные, значение которых не существенно, то в switch придется перечислить все возможные комбинации
     
  18. Unixon

    Unixon Оракул Модератор

    Судя по коду, это не прокатит. По крайней мере, не в лоб. Понадобятся две битовые карты на каждый случай: само значение и маска для значимых бит.

    Код (C):

    #define N_INPUT_PINS 6
    #define N_OUTUT_PINS 4
    #define N_CASES 3
    const uint8_t INPUT_PINS[N_INPUT_PINS] = {6,5,4,3,2};
    const uint8_t OUTPUT_PINS[N_OUTPUT_PINS] = {10,9,8,7};
    const uint8_t VALUE_BITS[N_CASES] =
    {
      B00010001,
      B00010010,
      B00010011
    };
    const uint8_t MASK_BITS[N_CASES] =
    {
      B00010011,
      B00010011,
      B00010111
    };
    const uint8_t OUTPUT_BITS[N_CASES] =
    {
      B11111110,
      B11111101,
      B11111011
    };

    uint8_t readPins()
    {
      uint8_t result = 0;
      for (uint8_t i=0; i<N_INPUT_PINS; i++)
      {
        result <<= 1;
        result |= 1 & digitalRead(INPUT_PINS[i]);
      }
      return result;
    }

    void writePins(uint8_t value)
    {
      for (uint8_t i=0; i<N_OUTPUT_PINS; i++)
      {
        digitalWrite(OUTPUT_PINS[i], value&1);
        value <<= 1;
      }
    }

    void setup()
    {
      for (uint8_t i=0; i<N_OUTPUT_PINS; i++)
      {
        pinMode(OUTPUT_PINS[i], OUTPUT);
      }
    }

    void loop()
    {
      uint8_t x = readPins();
      bool quit = false;
      for(uint8_t i=0; i<N_CASES; i++)
      {
        if (VALUE_BITS[i] == (MASK_BITS[i] & x))
        {
          writePins(OUTPUT_BITS[i]);
          quit = true;
        }
        if (quit) break;
      }
      if (!quit) writePins(0xff);
    }
     
     
    Последнее редактирование: 10 июл 2017
  19. mcureenab

    mcureenab Гуру

    Там проще. Одна полная комбинация. Две с одним незначащим битом. Они породят два case каждая. И все прочее. Так что ничего страшного.
     
  20. Unixon

    Unixon Оракул Модератор

    Вот, что-то такое должно получиться...