2016-03-12 4 views

ответ

1

Оба утверждения равны, как и на языке C, нет понятия булева. Таким образом, true представлена ​​как 1 и false представляется как 0.

См https://www.le.ac.uk/users/rjm1/cotter/page_37.htm

+2

На самом деле, 'false' представляется 0, но все остальное представляет' true'. Итак, -3, 0.5 и ''0'' - все верно. – AustinWBryan

+3

@AustinWBryan Хотя значения, такие как '-3',' 0,5' или ''0'', считаются истинными (или, скорее, неверными), результат булевого выражения всегда равен' 0' или '1' , –

+0

Я знаю. Я просто хотел, чтобы это было там, что другие значения представляют «истину», потому что у этой информации эта информация отсутствует. – AustinWBryan

3

В первом, a>b?1:0, присвоить целое значение 1 или 0 переменной c.

Во втором, (a > b), вы присваиваете логический результат сравнения переменной c.

Семантически большая разница, в реальном мире нет никакой разницы, так как в C значение для true равно 1, а значение для false - 0. Таким образом, c получит значение 1 или 0 в любом случае.

-1

Разница заключается в выполнении, а не в результате. Язык C, который широко используется во встроенных системах; выполнение является важным соображением.

В случае утверждения 1 результат выражения a>b будет оцениваться и на основе вывода того, что значение будет присвоено переменной c. Во втором случае непосредственно присваивается вывод выражения a>b.

Выполнение мудрый второй оператор является более оптимальным. Первый оператор основан на решении, а второй - простое назначение. Это не требует упоминания, но у вас есть больше гибкости в случае утверждения, поскольку вы можете делать с ним намного больше, чем назначать 1 и 0

С точки зрения аппаратного обеспечения, выполняемого , для оператора потребуется больше циклов, чем оператор 2.

+0

Нет никакой разницы в исполнении, если вы не используете действительно плохой компилятор. –

+0

Да, но мы не говорим о оптимизации компилятора. Это скорее концептуальный вопрос, чем следует указать на программирование и разницу. То, что я сделал. Другие точки очевидны – Sharad

+0

C не определяет, как '? : 'выполняется. Если он определит некоторую модель исполнения, то я бы не получил идентичный код из * не оптимизирующего * компилятора. –

9

На обычном компиляторе нет абсолютно никакой разницы (за исключением того, что у первого есть больше нажатий клавиш, а во втором - ненужные круглые скобки (...)). На некотором действительно сильно оптимизирующем компиляторе одна или другая форма может быть медленнее.

Настоящий результат от x > y представлен как 1, а false - 0.Цитирование ISO/IEC 9899: Комитет 201x Проект 12 апреля 2011 N1570:

Каждый из операторов < (менее), > (больше), <= (меньше или равно), и >= (больше или равно) будет давать 1, если указанное соотношение является истинным и 0 если оно ложно ). в результате имеет тип int.

И a ? b : c это выражение, которое, если a оценивается как истина дает значение b иначе c.

Таким образом, результат 2 идентичен. На самом деле, если вы компилируете этот код и разобрать его, вы заметите, что скомпилированный код может отличаться либо:

int test1(int a, int b) { 
    return a > b; 
} 

int test2(int a, int b){ 
    return a > b ? 1 : 0; 
} 

Составлено на GCC 4.7.2, x86-64, с отладки на (-g) - которые должны обеспечить здесь, что все оптимизаций отключены как можно больше - тогда разобрали с objdump -d foo.o:

0000000000000000 <test1>: 
    0: 55      push %rbp 
    1: 48 89 e5    mov %rsp,%rbp 
    4: 89 7d fc    mov %edi,-0x4(%rbp) 
    7: 89 75 f8    mov %esi,-0x8(%rbp) 
    a: 8b 45 fc    mov -0x4(%rbp),%eax 
    d: 3b 45 f8    cmp -0x8(%rbp),%eax 
    10: 0f 9f c0    setg %al 
    13: 0f b6 c0    movzbl %al,%eax 
    16: 5d      pop %rbp 
    17: c3      retq 

0000000000000018 <test2>: 
    18: 55      push %rbp 
    19: 48 89 e5    mov %rsp,%rbp 
    1c: 89 7d fc    mov %edi,-0x4(%rbp) 
    1f: 89 75 f8    mov %esi,-0x8(%rbp) 
    22: 8b 45 fc    mov -0x4(%rbp),%eax 
    25: 3b 45 f8    cmp -0x8(%rbp),%eax 
    28: 0f 9f c0    setg %al 
    2b: 0f b6 c0    movzbl %al,%eax 
    2e: 5d      pop %rbp 
    2f: c3      retq 

Вы можете увидеть код для 2 функций совершенно идентичны; вы не можете определить, какой из них был скомпилирован. Выражение на 3-х линий:

d: 3b 45 f8    cmp -0x8(%rbp),%eax 
    10: 0f 9f c0    setg %al 
    13: 0f b6 c0    movzbl %al,%eax 

Первый сравнивает b к a и устанавливают флаги процессора надлежащим образом. Второй устанавливает al (младший байт регистра eax/rax) до 1, если результат «больше» (обратите внимание, что сравнение было инвертировано выше!), 0 в противном случае; И третий, movzbl zero-extends байт до 32-битного целого числа, так как мы возвращаем здесь int.

+0

Просто из любопытства эксперта, не являющегося «компилятором», не могли бы вы объяснить, как и в каких обстоятельствах первое утверждение может быть быстрее второго? Я понимаю, что второй может быть быстрее, но не может понять, как это возможно. +1. – nicola

+1

Ну, это был бы действительно плохой компилятор. Это просто теоретико, но если вам понадобится ** jump **, чтобы произойти для '?:' На определенной архитектуре, тогда вам понадобится ** jump **, чтобы произойти и для '>', чтобы установить 1 или 0 правильно , Таким образом, может случиться так, что скачок будет упорядочен по-разному и вызовет ошибки прогнозирования ветвлений. Я хочу сказать, что создание таких утверждений о том, что код генерируется из исходного кода C, очень смелое. –

Смежные вопросы