Можем ли мы присвоить значение внутри оператора if? - PullRequest
0 голосов
/ 01 марта 2019
#include <stdio.h>
void main()
{
    int x = 0;
    if (x = 0)
      printf("It's zero\n");
    else
      printf("It's not zero\n");
}

Почему утверждение if (x = 0) не является ошибкой?Можем ли мы присвоить такое значение в операторе if?Почему он не генерирует ошибку и почему выполняется оператор else?

Ответы [ 3 ]

0 голосов
/ 01 марта 2019

Да, разрешено присваивать значение внутри оператора if.Это очень удобно, между прочим, когда вы хотите вызвать функцию и проверить, что она возвращает ошибку:

int rc;
if ((rc = check())) {
    // here rc is non-zero, often an indication of a failure
}

Обратите внимание, как я поставил лишнюю пару скобок вокруг своего назначения - так как этоПри таком вездесущем источнике путаницы компиляторы обычно предупреждают о назначении в блоке if, предполагая, что вы могли сделать опечатку.Дополнительная пара скобок проясняет для компилятора, что это именно то, что я и имел в виду.

Кстати, здесь не создано никакого специального исключения, валидность этого синтаксиса вытекает из общей грамматики C - оператор присваивания оценивается как назначенныйзначение.

0 голосов
/ 01 марта 2019

В C единственным требованием для оператора if является то, что оно содержит выражение .Истинность утверждения основана на том, оценивает ли выражение ноль.

Оператор присваивания также оценивает присвоенное значение, поэтому if(a = 0) будет ложным, тогда как if(a = x), где x != 0 будет истиной.

Поскольку оператор присваивания является выражением,Допустимо помещать в оператор if, хотя частая ошибка новичка заключается в использовании оператора присваивания, где они намеревались использовать оператор теста на равенство ==.

Один из способов избежать этого - ошибкаесли любая из сторон сравнения является r-значением, поместите его слева, чтобы при случайном использовании =, где вы имели в виду ==, вы получите ошибку компиляции.Сравните:

if(p = NULL) // Valid syntax
    ...

if(NULL = p) // Syntax error
    ...
0 голосов
/ 01 марта 2019

Да, это совершенно правильный синтаксис, нет никаких оснований запрещать это.

Цитирование C11,

[...] Выражение присваивания имеетзначение левого операнда после присваивания.[...]

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

В вашем случае переменнаяx содержит значение 0 после назначения, а if (0) равно FALSY , поэтому выполняется блок else.


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

предупреждение: предлагать скобки вокруг присваивания, используемого в качестве значения истинности [-Wparentheses]

 if (x = 0)
 ^

Есливы уверены, что делаете, вы можете обернуть условие if выражением присваивания в дополнительную пару скобок, и все будет хорошо.

...