Тонкости C/C++

Тема в разделе "LANGS.C", создана пользователем Nafanya, 5 фев 2011.

  1. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    Кто-нибудь может привести пример кода, где бы был необходим унарный плюс.
     
  2. krabz

    krabz New Member

    Публикаций:
    0
    Регистрация:
    26 май 2010
    Сообщения:
    135
    Nafanya
    Да это походу стебутся над Вами на собеседованиях. Ну какой нормальный чел будет писать такой нечитаемый гуанокод? Я бы так и сказал, что всегда пишу читаемый и сопровождаемый код, поэтому такими извратами не страдаю. Вообще в разных языках разные понятия о приоритете операций, поэтому я лично вообще не полагаюсь на приоритеты и всегда явно разруливаю скобками порядок вычисления.
     
  3. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    Я думал унарный плюс от (-7) сделает её (+7), так вот прикол - он даже и этого сделать не может:) (сейчас попробывал)

    Да я еще пока не ходил, только готовлюсь, все повторяю. Судя по предыдущим собеседованиям синтаксис спрашивают серьезно и в глубину... Вот пытаюсь все по полочкам разложить.
    А если сильно докапываться будут, скажу что у меня диплом на руках и универ уже мои знания проверил, можете не париться.:) Или что-то в этом духе, если сильно разозлят извратом.
     
  4. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    нет не так более того в си и си++ тут разные правила
    для си это вообще не скомпилируется а для си++ нормально
    вычисляется оно так
    1) j ? k : l == expr
    2) i = expr = m;
    так вот для си это expr (результат оператора ?:)
    не lvalue
    поэтому даже не скомпилится
    а для си++ lvalue так что все ок
     
  5. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    osox
    VS 2010; язык C++ - выражение i=i?k:l=5; вычисляется (i=i?k:dntknw:l=5)); то бишь не по правилам приоритетов, т.к. операция ?: имеет приоритет выше =;
    Доказательство:
    Код (Text):
    1. i=i?k:l=5;
    2. 00413545  cmp         dword ptr [i],0  
    3. 00413549  je          main+56h (413556h)  
    4. 0041354B  mov         eax,dword ptr [k]  
    5. 0041354E  mov         dword ptr [ebp-0E8h],eax  
    6. 00413554  jmp         main+66h (413566h)  
    7. 00413556  mov         dword ptr [l],5 //l=5;
    8. 0041355D  mov         ecx,dword ptr [l]  
    9. 00413560  mov         dword ptr [ebp-0E8h],ecx  
    10. 00413566  mov         edx,dword ptr [ebp-0E8h]  
    11. 0041356C  mov         dword ptr [i],edx
     
  6. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    ну и где вы тут видите (i=i?k:dntknw:l=5)); ?
    вот для с++
    Код (Text):
    1.     i = j ? k : l = m;
    2. 0040101B 8B 45 F4         mov         eax,dword ptr [j]
    3. 0040101E 85 C0            test        eax,eax
    4. 00401020 74 05            je          main+27h (401027h)
    5. 00401022 8B 45 F0         mov         eax,dword ptr [k]
    6. 00401025 EB 09            jmp         main+30h (401030h)
    7. 00401027 8B 45 FC         mov         eax,dword ptr [m]
    8. 0040102A 89 45 F8         mov         dword ptr [l],eax
    9. 0040102D 8B 45 F8         mov         eax,dword ptr [l]
    10. 00401030 89 45 EC         mov         dword ptr [i],eax
    а для си это несоберется
    если бы это было так (i=i?k:dntknw:l=5));
    то это и для си бы работало при таком порядке
    но не работает и явно пишет
    error C2106: '=' : left operand must be l-value
    потому что имеем expr == i?k:l
    i = expr = m;
    потому что результат ?: в си rvalue
     
  7. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.330
    унарный плюс ничего не делает... возвращает операнд в той же форме... про унарный минус понятно... самое важное, что надо запомнить - то, что унарные операции выполняются справа-налево, а бинарные слева-направо... меньше думайте, больше пишите, с вашими комплексами вы ни в одну контору не попадете...

    не пишите такой xeрни никогда... вам с ней прямая дорога на roвнокод.ру, можно кстати уже второй ваш семпл туда запостить)))
     
  8. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    osox
    i = j ? k : l = m;
    Ваш код:
    1) Проверка j ноль или нет
    2)Если не ноль, то i=k
    3)Если ноль, то l=m; затем i=l;

    l=m
    Код (Text):
    1. 00401027 8B 45 FC         mov         eax,dword ptr [m]
    2. 0040102A 89 45 F8         mov         dword ptr [l],eax
    Таким образом выражение вычисляется i = j ? k :dntknw: l = m), а должно i = (j ? k :l) = m, то есть i всегда должно быть равным m а в случае 2) мы как видите имеем i=k, чего не должно быть.
     
  9. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    ошибся на самом деле для си++
    и правда так (i=i?k:dntknw:l=5));
    а вот для си так
    1) j ? k : l == expr
    2) i = expr = m;
    поэтому не компилится
    вообще чертов синтаксис одна и таже конструкция в си и в си++ работает совершенно по разному си такое не пропустит а си++ получается плевал на приоритет в тернарном операторе а си честно пишет
    error C2106: '=' : left operand must be l-value
     
  10. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.330
    насколько я помню - все опять же абсолютно так, как и должно быть))
     
  11. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    Бывает, не ошибается только тот кто ничего делает...

    Rel
    Да нет же, оператор ?: должен иметь более высокий приоритет, чем присваивание и выполниться первым.
     
  12. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.330
    по определению тернари оператора:
    Код (Text):
    1.  a = b ? c : d
    эквивалентно
    Код (Text):
    1. if(b) { a = c; }
    2. else  { a = d; }
    в вашем случае:
    Код (Text):
    1. i = j ? k : l = m
    эквивалентно:
    Код (Text):
    1. if(j) { i = k; }
    2. else  { i = l = m; }
    оператор вычисляется именно так, как должен вычисляться... так в чем вопрос?
     
  13. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    в том что для си это не так
    именно из за приоритета а си++ плевал и работает как if else
    несмотря на приоритет
     
  14. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    Rel

    i = j ? k : l = m
    Должно быть так:
    1)Выполняется оператор ?: с самым высоким приоритетом , то есть в зависимости от j значение выражения (j ? k : l) равно либо k либо l
    2) Выполняется правый оператор присваивания, промежуточное выражение принимает значение равное m
    3)Выполняется левый оператор присваивания i=m;
    4)Всё

    в вашем случае:
    Код (Text):
    1. Код:
    2. i = j ? k : l = m
    не эквивалентно:
    Код (Text):
    1. Код:
    2. if(j) { i = k; }
    3. else  { i = l = m; }
    эквивалентно:
    Код (Text):
    1. Код:
    2. if(j) { temp= k; }//Выполняется
    3. else  { temp = l ; }//тернарный оператор
    4. temp=m;//Выполняется правое присваивание
    5. i=temp;//Выполняется левое присваивание
     
  15. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.330
    Nafanya
    osox
    вот как вы мне надоели... читаем:
    причем читаем несколько раз... до наступления понимания слов...

    нет... это не так... я уже писал почему... вы не слушаете, или не желаете понимать...
    но подойдем немного с другого угла, из перекрестной статьи (про перегрузку оператора равно):
     
  16. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    Rel
    Ясно, спасибо.

    не понятно почему, странно это как-то.
    Ведь i=(j?k:l)=m;
    (j?k:l) -тоже это conditional-expression которое является lvalue;
     
  17. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.330
    видимо это - rvalue, как и все другие результаты встроенных операций)
    а в цпп его можно "использовать как lvalue":
    Код (Text):
    1.  (a ? b : c) = 1;
    еще вам вопрос, что такое:
    Код (Text):
    1. a = x ?: y;
     
  18. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    Rel
    a = x ?: y;
    Компилятор пишет, что это синтаксическая ошибка.
    Что такое цпп? цементно песчаное покрытие?:)
     
  19. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.330
    а... ну это наверное в GNU расширении только... mingw собирает без проблем...
    в результате это выражение эквивалентно:
    Код (Text):
    1. a = x ? x : y
    но, если x - выражение, то оно вычисляется один раз - в условии...

    цпп - cpp - c++ - си плюс плюс
     
  20. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    после пары часов все это кажется
    крайне мутной хренью вообщем
    вывел для себя несколько новых правил

    в с++ тернарный оператор может обрабатывать
    присваивание как часть условия
    оно и будет результатом
    но не больше например ,(comma) уже не войдет
    в условие остальное мы знали
    а именно в чистом си он rvalue всегда
    а в с++ зависит от типа результата
    теперь понятны все его "заморочки"
    в чистом си же присваивание останется "за бортом"
    и будет рассматриватся как отдельная часть выражения