Небольшой тест по программированию на C/C++

Тема в разделе "Флудилка", создана пользователем AlexU, 17 янв 2016.

  1. AlexU

    AlexU Гуру

    Есть код скетча:
    Код (C++):

    LiquidCrystal lcd.............. // прошу не заострять внимания на декларацию 'lcd' на суть теста не влияет

    void setup() {
      char ch1 = 0xD0;    // создаем переменную 'ch1' и задаём значение 0xD0
      if (ch1 == 0xD0) {  // проверяем равно ли значение переменной 'ch1' значению 0xD0
        lcd.print("D0");      // если значение переменной 'ch1' равно 0xD0, то на дисплей выводим "D0"
      }
      char ch2 = 0x30;    // создаем переменную 'ch2' и задаём значение 0x30
      if (ch2 == 0x30) {  // проверяем равно ли значение переменной 'ch2' значению 0x30
        lcd.print(ch2);       // если значение переменной 'ch2' равно 0x30, то на дисплей выводим "0"
                                        // (0x30 -- это код символа "0")
      }
    }

    void loop() {
      // put your main code here, to run repeatedly:

    }
    Собственно вопрос, что будет отображено на ЖК дисплее?
     
  2. shpock

    shpock Гик

    0
     
  3. AlexU

    AlexU Гуру

    Наверно использовали Arduino IDE для проверки, так?
    "0" на дисплее означает, что сработало только второе условие (ch2 == 0x30), есть варианты почему первое условие (ch1 == 0xD0) не сработало?
     
  4. shpock

    shpock Гик

    та да
    наверное из-за преобразования типа данных, но вот до конца не понимаю что и как.
     
  5. DrProg

    DrProg Вечный нерд

    Да. Тут вот написано коротко об отличиях. On Arduino, char is int8_t but byte is uint8_t. Так сработает:
    Код (C++):
      char ch1 = 0xD0;    // создаем переменную 'ch1' и задаём значение 0xD0
      if ((byte)ch1 == 0xD0) {  // проверяем равно ли значение переменной 'ch1' значению 0xD0
        Serial.println("D0");      // если значение переменной 'ch1' равно 0xD0, то на дисплей выводим "D0"
      }
     
    Последнее редактирование: 17 янв 2016
    ИгорьК нравится это.
  6. Максимус-Бог

    Максимус-Бог Убийца матрёшек

    условие выполнится, но потом выполнится второе и загородит первое
    Если не так поправьте.
     
  7. AlexU

    AlexU Гуру

    Не так. Скажу больше, если дизассемблировать бинарник, то можно увидеть, что компилятор вообще выкинул из рассмотрения следующие строчки исходного кода:
    Код (C++):
    char ch1 = 0xD0;    // создаем переменную 'ch1' и задаём значение 0xD0
      if (ch1 == 0xD0) {  // проверяем равно ли значение переменной 'ch1' значению 0xD0
        lcd.print("D0");      // если значение переменной 'ch1' равно 0xD0, то на дисплей выводим "D0"
      }
    , т.к. оптимизатор компилятора принял решение, что переменная 'ch1' со значением '0xD0' не равна константе со значением '0xD0' -- соответственно код "мёртвый" и его можно выкинуть в целях уменьшения объема бинарника. Вот такая вот чепуха получается, на первый взгляд.

    Да так сработает, и проблема кроется действительно в знаковости или беззнаковости переменных или констант. Знаковая переменная ch1 будет равна беззнаковой константе, только если переменной задано положительное значение (второе условие в скетче -- 0x30). А если задать отрицательное значение (в первом условии значение 0xD0 -- это '-48'), То в этом случае компилятор скажет, что переменная не равна константе, т.е. '-48' != '208', что собственно и является истиной.

    Проблему можно решить:
    1. явным преобразованием типов, как указал DrProg;
    2. задать опцию компилятору -funsigned-char (имеется ввиду компилятор avr_g++, Arduino IDE такой использует), т.е. указать компилятору рассматривать тип char как беззнаковый.
     
    DrProg и shpock нравится это.
  8. DrProg

    DrProg Вечный нерд

    Что значит "загородит"? Это два независимых условия. Если нужно чтобы выполнилось что то одно, пользуйте if...else.
     
    ИгорьК нравится это.