2016-05-11 3 views
0
if ((vnd = (struct diam_vnd_t *)g_hash_table_lookup(vendors,vend))) {...} 

Можете ли вы сказать мне, почему это назначение, но не логическое выражение в скобках? И в какой ситуации это задание можно считать «истинным» или «ложным»?Как оператор присваивания в выражении if служит условием?

+2

Любой полууровневый компилятор будет предупреждать об этом по уважительным причинам – Olaf

+0

@Olaf Даже после использования '((..))'? –

+0

@SouravGhosh: Хм, я их действительно не замечал. Хорошо, я перехожу к «нужно». Проверено с помощью gcc: оно даже предлагает скобки, чтобы избежать предупреждения (и они работают). Heck, это должно требовать явного сравнения для подавления предупреждения, не менее заметного. Спасибо, что сообщили мне. – Olaf

ответ

2

Цитирование C11, глава §6.5.16, операторы присваивания (курсив мой)

Оператор присваивания сохраняет значение в объекте, обозначенном левым операндом. Значение выражения имеет значение левого операнда после присвоения, 111), но не lvalue.

Итак, первое задание будет происходить, а затем значение, которое было назначено будет использоваться в качестве условного оператора в if.

Таким образом, в случае

if (p = 0) 

оценит ЛОЖЬ и

if (p = 5) 

будет TRUE.

+1

спасибо, это именно то, что мне нужно, я приму это. – SWIIWII

0

C считает, что любое ненулевое значение должно быть true, и что-либо 0, чтобы быть ложным.

Значение этого присвоения равно значению, которое оно присваивает vnd, в данном случае struct diam_vnd_t *. Оператор if проверяет, является ли vndNULL после назначения.

Это было бы эквивалентно:

vnd = (struct diam_vnd_t *)g_hash_table_lookup(vendors,vend); 
if (vnd) {...} 
+0

C очень хорошо имеет булевский тип. И в состоянии любое выражение преобразуется в логический результат (тип 'int', хотя). – Olaf

+0

Тип 'bool' - это просто' unsigned int'. По сути, язык имеет дело с «нулевым» и «ненулевым» как булевыми, а не «истинными»/«ложными» атомами. – Alexander

+0

Нет, '_Bool' - это отличный целочисленный тип без знака со значениями' 0' и '1'' bool' - это макрос в 'stdbool.h', который сопоставляется с' _Bool'. Это ** не ** 'unsigned int'. Примечание: Это стандартный C, а не некоторый homeprew 'typedef'! О интерпретации «истина»/«ложь»: попробуйте '_Bool b = 4;' или 'printf ("% d ", (bool) 5);'. Обратите внимание, что логическая логика не определяет, как должны быть представлены «истинные»/«ложные». Часто они находятся на '0' /' 1', потому что это упрощает математические операции. См. Википедию. – Olaf

0

Логический оператор «равно» является ==

Когда вы говорите vnd = (struct... вы назначаете все после = переменной vnd. Если вы хотите использовать истину или ложь, вам необходимо использовать ==

0

Назначение всегда выполняется с одним знаком равенства. =

int i; 
i = 0; //assignment 

Назначает 0 до целого под названием i.

То же самое происходит с вашим оператором if. Независимо от того, является ли это в выражении if, это не имеет значения.

(vnd = (struct diam_vnd_t *)g_hash_table_lookup(vendors,vend)) 

Чтобы сделать булево выражение, вам необходимо использовать ==.

(vnd == (struct diam_vnd_t *)g_hash_table_lookup(vendors,vend)) 

Это возвращает истину или ложь на основе сравнения 2 пунктов

+0

'int i = 0;' is ** not ** присвоение. – Olaf

+0

@Olaf 'int i; // declaration', 'i = 0; // присваивание' <- Как это? – element11

+0

Это разные вещи! – Olaf