C/C++

Логический оператор И и ИЛИ в Си

Не понимаю почему вот так, вот кусок кода:
 int menu() 
{
int c;
do
{
printf("Сделайте выбор:\n\n");
printf("1 - Задание 1\n");
printf("2 - Задание 2\n");
printf("3 - Выход\n");
scanf_s("%d", &c);

if (c != 1 || c != 2 || c != 3)
printf("Ошибка! Вы выбрали неверную операцию.. Попробуйте снова\n");
}
while (c != 1 || c != 2 || c != 3);
return c;
}
Почему тут НЕЛЬЗЯ использовать логический оператор ИЛИ ( || ), а вместо него надо использовать И (&&) ? Если я поставлю ||, мне будет выдаваться ошибка C6289
https://learn.microsoft.com/en-us/cpp/code-quality/c6289?view=msvc-170

Я прочел эту статью от майкрософт, но если честно ничего не понял. По моей логике, если к примеру пользователь введет 1, то при такой записи с оператором И
 if (c != 1 && c != 2 && c != 3)  
Единица равна единице, но 2 НЕ равна единице и три тоже не равно единице, так как при оператор && надо чтобы все условия одновременно срабатывали, то типо это условие не сработает, потому что у переменной не может быть несколько значений, с не может быть одновременно быть равной 1 или 2 или 3. А вот с логическим оператором или по-моему все очень даже логично, ему ж надо чтоб только одно условие срабатывало и все будет ок тогда. Не понимаю, объясните пожалуйста.
В случае с ИЛИ это выражение истинно абсолютно всегда, а значит равносильно просто
if (true). Использовать можно, но это не имеет никакого смысла.

В случае с И это уже условие, которое может быть как истинным (если число не 123) так и ложным (если число 123)
Владимир Лосев
Владимир Лосев
34 940
Лучший ответ
Иван Шевляков почему истинно абсолютно всегда? Ввод пользователя 1, условие ложно
Владимир Лосев
 x=-3 | AND: True  | OR: True 
x=-2 | AND: True | OR: True
x=-1 | AND: True | OR: True
x= 0 | AND: True | OR: True
x= 1 | AND: False | OR: True
x= 2 | AND: False | OR: True
x= 3 | AND: False | OR: True
x= 4 | AND: True | OR: True
x= 5 | AND: True | OR: True
x= 6 | AND: True | OR: True
Отрицания вносят некоторую путаницу. А так же конструкции где true означает ошибку.
Понятнее становится если каждое отрицание вынести за скобки.
if (!(c==1 || c ==2 || c==3 )) cout << "ошибка".
А когда вносите его, то или меняются на и.
if ( c!=1 && c!=2 && c!=3 ) cout << "ошибка".
если с = 1, то с!=1 = 0, и все выражение равно нулю, ошибка не срабатывает.
если с = 4, то с!=1 = 1 , с!=2 = 1, с!= 3 = 1, все выражение = 1. Ошибка срабатывает.
В данном примере ИЛИ нельзя использовать, потому что возвращает true если хотя один из его операндов тоже является true, если все false то возвращается false. Когда пользователь вводит цифру 1 в условии конструкции if с != 1 вернет true и вычисление на этом остановится, дальнейшие сравнения уже не пойдут и всё выражение примет значение true в итоге выводится сообщение, также условие цикла будет true, а значит повторный ввод.

Оператор И нужно использовать потому что этот оператор, работает совсем иначе, оператор И вернет true если все его операнды true, а не только один из них, оператор И начинает сравнение с левого выражения с != 1 если true вычисление продолжается c != 2 и так до конца, если одно из сравнений даст false вычисление остановится и всё выражение примет false, если все сравнения возвращают true то всё выражение целиком становится true.

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