09.29 Логические выражения и условный оператор; побочный эффект; EJudge
Работа в EJudge
Вход по условию задачи EJudge: HelloWorld 'Привет, два мира!'
Input:Написать программу, которая выводит две строки Hello, world! одну под другой
Output:Hello, world! Hello, world!
- Приоритет условия на сайте над условием в EJudge; полная формулировка условия
- Порядок тестирования: ввод, вывод и сравнение с эталонным выводом
- Понятие «посылки». «Парковка на слух».
- Штрафы: минимальный за повторную посылку, 50% за просрок
Асимметричность операции присваивания
В чём проблема с такой записью?
Имя переменной в Си выражении — замена адреса ячейки памяти. Использование имени — извлечение содержимого этой ячейки.
Понятие lvalue (оно же LHS). Левая часть присваивания — т. н. «адресное выражение», что-то, куда можно присвоить значение
Всё присваивание целиком — это выражение (результат правой части), изменение значений по какому-то адресу — побочный эффект
Верно также для операций вида ✓=, ++ и --
Задать два целых. Поделить первое на второе, результат вывести. Домножить результат на второе число, вывести. Использовать ✓=.
Логические операции
В современном Си есть тип bool, в ANSI Си (стандарт C90) — нет.
bool — это целочисленный тип из двух значений (true == 1, false == 0)
Логические операции || (OR, дизъюнкция), && (конъюнкция) и ! (NOT, отрицание) возвращают 0 или 1
Принимают они любое значение, которое можно преобразовать к целому
0 — это false; остальное — true
Написать программу, которая выводит результат дизъюнкции, конъюнкции для константных выражений типа int и float (или double, неважно) и отрицания для константных выражений типа float - Для каждой операции подобрать такие значения, чтобы получалось 0 и 1 (всего, стало быть, по два варианта на каждую из трёх операций)
Сравнения
Всего 6: <, >, <=, >=, ==, !=
Возвращает 0 или 1 (bool)
Сравнивать можно:
- Выражения одного типа
Выражения приводимых типов (числовых, но и адресных тоже, например)
В чём проблема сравнения знаковых и беззнаковых чисел?
сравнение двух вещественных чисел на точное равенство
(НЕ УСПЕЛИ) Тернарная операция
printf("%d %d %d %d", a, b, c, a ? b: c);
Неравенство треугольника: вывести 1 или 0 в зависимости от того, может ли быть образован треугольник с положительными (не проверять) вещественными сторонами.
Про scanf
Получает в качестве второго параметра значение выражения "var" — 5
В чём проблема написать функцию ввода input(), которая работала бы так
Как эту проблему можно решить?
⇒ «Магия» scanf() (
оба утверждения не верны! потому что магия…)
- Ввести можно только переменные
Перед каждой переменной надо ставить &
Модифицировать задачу про неравенство треугольника так, чтобы числа вводились
TODO надо ли упражненьки помещать в EJudge? Мне кажется, нет — они слишком простые
(НЕ УСПЕЛИ) Условный оператор
Общий вид: ::= if ( <выражение> ) <оператор> [ else <оператор> ]
Выражение — интерпретируется как 0 или не 0
оператор — один оператор
- Если надо больше, заключаем операторы в фигурные скобки
Если вдруг надо ни одного, пишем одинокую «;»
Ввести два числа, вывести, какое больше
Переписать задачу про неравенство треугольника с помощью if:
- При вводе хотя бы одного отрицательного числа программа ругается на это и завершается
- Выводится, можно ли построить треугольник
(НЕ УСПЕЛИ) Точки последовательных вычислений
Повторение из лекции о точках последовательных вычислений:
Про EJudge (окончание)
EJudge: DivMul 'Умножение и деление'
Ввести два целых числа в строке через пробел. Вывести в отдельных строках сначала их произведение, а затем — результат целочисленного деления первого на второе
20 7
140 2
(да, это простая задача — осваиваем В/В EJudge)
Д/З
1. Ввести вещественное х; если 1.0<=х<=3.0, вывести "FIRST", если 2.7<=х<=6.8, вывести "SECOND"; при невыполнении ни одного из двойных неравенств, вывести "NONE".
2. Ввести вещественные х, у. Если точка (х,у) принадлежит области, показанной на картинке, вывести "YES", иначе вывести "NO".
3. Ввести вещественные a, b, c. Рассчитать корни биквадратного уравнения ax⁴ + bx² + c = 0. Если a=0, то вместо корней вывести "ZERO_A". Если корней нет, вывести "NO_ROOTS". В противном случае вывести (через пробел) корни, упорядоченные по возрастанию. Если корень двойной, вывести его два раза.

Логические операции && и ||