IF....

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

  1. funyfizik

    funyfizik Нерд

    Столкнулся с такой интересной вещью:
    Почему если использовать эту конструкцию
    Код (Text):
    boolean a;

    if (a = true)
    {
    .....
    .....
    }
    компилятор не выдает ошибку?
     
  2. Alex19

    Alex19 Гуру

    Ошибка по невнимательности, надо ==
    Код (Text):

    if (a == true)
    {
    .....
    .....
    }
     
     
  3. funyfizik

    funyfizik Нерд

    ты не понял суть вопроса, я знаю что это ошибка, но IDE ее не видит о_О
     
  4. Alex19

    Alex19 Гуру

    Да извиняюсь, не проснулся:(.

    Точного ответа у меня нет, тут идет присвоение и конструкция в скобка будет равна true, только, что проверил.


    Код (Text):

    int led = 13;

    void setup() {              
      pinMode(led, OUTPUT);
      digitalWrite(led, LOW);
    }

    void loop() {
      boolean a;

      if (a = true)
      {
        digitalWrite(led, HIGH);
      }        
    }
     
     
  5. funyfizik

    funyfizik Нерд

    да понятно, он делает свою работу, но почему не проверяет что в скобках нет операции сравнения? Если это проделать с int или с другим типом данных то он пишет ошибку конечно же))))))) БАГ?
     
  6. Alex19

    Alex19 Гуру

    Ради прикола, кинул в Студию и написал на C#, компилятор тоже не нашел ошибки.
    Тут увы не знаю, если студия не нашла ошибки, навряд ли это баг.

    UPD. Видимо придется с этим жить, вот что пишут
    http://arduino.cc/en/Reference/If

    С анг. у меня туго, вот перевод гугла
     
    Последнее редактирование: 20 окт 2014
  7. Tomasina

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

    пиши так:
    Код (Text):
    if (a)
    {
    .....
    .....
    }
    Смысл тот же, но тут уже трудно ошибиться :)
     
    Alex19 нравится это.
  8. Unixon

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

    Здесь нет никакой ошибки, в C/C++ разрешено делать присваивание внутри условия. Чтобы не наступать на эти грабли с опечаткой "=" вместо "==", всегда ставьте константу первой в выражении, тогда компилятор будет на это ругаться.
     
  9. funyfizik

    funyfizik Нерд

    Здесь только описывается что это функция присвоения, а не говорят почему так работает, а не иначе
     
  10. funyfizik

    funyfizik Нерд

    Можно пример кода? Не пойму о какой константе идет речь
     
  11. Alex19

    Alex19 Гуру

    Полагаю, речь идет об этом if (true = a)

    Код (Text):

    int led = 13;

    void setup() {            
      pinMode(led, OUTPUT);
      digitalWrite(led, LOW);
    }

    void loop() {
      boolean a;

      if (true = a)
      {
        digitalWrite(led, HIGH);
      }      
    }
     
    Но если работаете с переменными, есть шанс получить ошибку, пример от Tomasina, по моему мнению лучше.
     
  12. funyfizik

    funyfizik Нерд

    Вывод - непонятная фича..... ВСЕМ СПАСИБО)

    хотя скорее всего это сделанно для гибкости языка программирования )))
     
  13. NR55RU

    NR55RU Гик

    Фитча на самом деле совершено понятная. :)
    При наличии списка равно-приоритетных операторов, выполнение их идет с права налево.
    Таким образом в вашем примере, сперва выполняется выражение присвоения, то есть переменной a присваивается значение true, после чего отрабатывает конструкция if.
    Именно подобная технология вообще дает возможность писать составные выражения. Компилятор её пропускает потому что это совершенно нормальная с точки зрения синтаксиса языка конструкция.
    По сути ваша запись эквивалентная такой:
    Код (Text):
    a = true;
    if ( a )
    {
    // ...
    }
    Иногда можно встретить "обратный" вариант, как уже приводили пример выше, например такой:
    Код (Text):
    if ( 25 = a )
    {
    // ...
    }
    Эта фитча основывается на том что все литералы в программе являются константой и компилятор узрит попытку изменить константу и выдаст ошибку на этапе компиляции.
    Такой стиль практиковался ранее, в настоящее же время если вы будите в компиляторе включать достаточно высокий уровень предупреждений, он вам выкинет предупреждение о том что у вас идет попытка присвоения в конструкции if, причем он программу скомпилирует но предупреждение покажет, ибо с точки зрения яыка это не ошибка. :)

    Инода человек пытается сократить код в ущерб читаемости влепливая в одну строчку все что влепить может, предупреждения компилятора отключает ибо мешают ему они а потом бац и фиг что работает. Включает предупреждения, а там ворох в котором он разобраться не может ибо пошел сознательно на составление выражений которые попадают под "подозрительные".

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

    В целом на этой "непонятной фитче" собственно и стоит весь язык по сути, иначе бы у вас на одно действие была бы одна строчка кода, получилось бы что то типа Ассемблера :)
    И выглядело бы вот такое выражение:
    Код (Text):
    a = 3 + 5 + 2;
    Вот так :
    Код (Text):
    a = 3;
    a + 5;
    a + 2;
    :) :)

    P.s. С++ вообще язык дающий огромную свободу, но за эту свободу приходится платить тем что именно программист должен следить за тем что он делает, ибо коварный замысел программиста компилятору не известен и он говорит, ну ок видимо ты знаешь что делаешь .. флаг тебе в руки :)
     
    Последнее редактирование: 20 окт 2014
    acos и Megakoteyka нравится это.
  14. geher

    geher Гуру

    Это не баг а фича.
    В языке программирования С всякое выражение присваивания возвращает значение, равное присваиваемому.
    А в условии оператора if можно ставить любое логическое или целочисленное выражение. Если результат 0, то условие ложно, если не 0 - истинно.
    Другой вопрос, что по хорошему компилятор должен выдавать предупреждение, что "что-то не так", но с точки зрения языка конструкция является синтаксически верной и осмысленной.
    Компиллятор, который используется Arduino IDE, кстати, ругается (выдает предупреждение):
    "warning: suggest parentheses around assignment used as truth value"