int a = 5;
int b = 6;
int c;
Первое заявление:Какая разница между этими двумя утверждениями?
c = a > b ? 1 : 0;
Второе заявление:
c = (a > b);
В чем разница между выше двух?
int a = 5;
int b = 6;
int c;
Первое заявление:Какая разница между этими двумя утверждениями?
c = a > b ? 1 : 0;
Второе заявление:
c = (a > b);
В чем разница между выше двух?
Оба утверждения равны, как и на языке C, нет понятия булева. Таким образом, true
представлена как 1 и false
представляется как 0.
В первом, a>b?1:0
, присвоить целое значение 1
или 0
переменной c
.
Во втором, (a > b)
, вы присваиваете логический результат сравнения переменной c
.
Семантически большая разница, в реальном мире нет никакой разницы, так как в C значение для true равно 1
, а значение для false - 0
. Таким образом, c
получит значение 1
или 0
в любом случае.
Разница заключается в выполнении, а не в результате. Язык C, который широко используется во встроенных системах; выполнение является важным соображением.
В случае утверждения 1 результат выражения a>b
будет оцениваться и на основе вывода того, что значение будет присвоено переменной c
. Во втором случае непосредственно присваивается вывод выражения a>b
.
Выполнение мудрый второй оператор является более оптимальным. Первый оператор основан на решении, а второй - простое назначение. Это не требует упоминания, но у вас есть больше гибкости в случае утверждения, поскольку вы можете делать с ним намного больше, чем назначать 1 и 0
С точки зрения аппаратного обеспечения, выполняемого , для оператора потребуется больше циклов, чем оператор 2.
Нет никакой разницы в исполнении, если вы не используете действительно плохой компилятор. –
Да, но мы не говорим о оптимизации компилятора. Это скорее концептуальный вопрос, чем следует указать на программирование и разницу. То, что я сделал. Другие точки очевидны – Sharad
C не определяет, как '? : 'выполняется. Если он определит некоторую модель исполнения, то я бы не получил идентичный код из * не оптимизирующего * компилятора. –
На обычном компиляторе нет абсолютно никакой разницы (за исключением того, что у первого есть больше нажатий клавиш, а во втором - ненужные круглые скобки (...)
). На некотором действительно сильно оптимизирующем компиляторе одна или другая форма может быть медленнее.
Настоящий результат от 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
.
Просто из любопытства эксперта, не являющегося «компилятором», не могли бы вы объяснить, как и в каких обстоятельствах первое утверждение может быть быстрее второго? Я понимаю, что второй может быть быстрее, но не может понять, как это возможно. +1. – nicola
Ну, это был бы действительно плохой компилятор. Это просто теоретико, но если вам понадобится ** jump **, чтобы произойти для '?:' На определенной архитектуре, тогда вам понадобится ** jump **, чтобы произойти и для '>', чтобы установить 1 или 0 правильно , Таким образом, может случиться так, что скачок будет упорядочен по-разному и вызовет ошибки прогнозирования ветвлений. Я хочу сказать, что создание таких утверждений о том, что код генерируется из исходного кода C, очень смелое. –
На самом деле, 'false' представляется 0, но все остальное представляет' true'. Итак, -3, 0.5 и ''0'' - все верно. – AustinWBryan
@AustinWBryan Хотя значения, такие как '-3',' 0,5' или ''0'', считаются истинными (или, скорее, неверными), результат булевого выражения всегда равен' 0' или '1' , –
Я знаю. Я просто хотел, чтобы это было там, что другие значения представляют «истину», потому что у этой информации эта информация отсутствует. – AustinWBryan