Лабораторная работа №3
ЗАДАЧИ НА ЛОГИЧЕСКИЕ И АРИФМЕТИЧЕСКИЕ ОПЕРАЦИИ
Основными арифметическими операциями являются: сложение ('+'), вычитание ('-'), умножение ('*') и деление ('/'). Порядок выполнения операций в выражении соответствует их приоритету. Операции с одинаковым приоритетом в выражении выполняются слева направо.
Операция деления ('/') выполняется согласно типу ее операндов. Если оба операнда являются целыми числами, то деление будет целочисленным. Если один из операндов является вещественным, то и результат будет вещественным. Например, пусть переменная x имеет целочисленный тип, а y действительный тип. Следующая таблица демонстрирует результаты деления для различных операндов:
Операция | Результат |
x = 7 / 3; | x = 2 |
y = 7 / 3; | y = 2.000000 |
y = 7.0 / 3; | y = 2.333333 |
y = (double)7 / 3; | y = 2.333333 |
Рассмотрим второй пример. При выполнении операции присваивания значения выражения переменной, сначала вычисляется значение выражения, а потом оно присваивается переменной. Поскольку операнды во втором примере являются целыми, то результатом деления 7/3 будет 2. Потом целочисленное значение 2 преобразовывается в действительное значение 2.000000 и присваивается действительной переменной y.
В четвертом примере перед выполнением операции деления происходит преобразование типа делимого из целого в вещественный. Поэтому деление будет производиться без потери точности.
Пример 1.1.1. Найти среднее арифметическое двух целых чисел a и b.
Результатом вычисления выражения (a + b)/2 может быть действительное число. Поэтому деление должно выполняться с сохранением точности. А для этого один из операндов необходимо преобразовать в действительный тип. Например, результат можно вычислить так: res = (a + b)/2.0. Программа имеет вид:
#include < stdio.h >
int a=3,b=7;
double res;
void main(void)
{
Операция | Результат |
x = 6 % 3 | x = 0 |
x = 8 % 3 | x = 2 |
x = -6 % 3 | x = 0 |
x = -8 % 3 | x = -2 |
/*scanf("%d %d",&a,&b);*/
res = (a + b) / 2.0;
printf("%lf\n",res);
}
Операция | Сокращение |
i = i + 1 | i++ |
i = i - 1 | i-- |
i = i + a | i += a |
i = i %a1 | i %= a |
Операция вычисления остатка в Си обозначается символом '%'. При этом остаток при делении отрицательного числа на положительное является отрицательным (хотя математически остаток при делении на число n должен лежать в промежутке от 0 до n – 1 включительно).
В языке Си при выполнении операций возможны синтаксические сокращения. Например, вместо i = i + 1 можно писать i ++. Если < op > – некоторая бинарная операция, то вместо i = i < op > a можно писать i < op >= a. Примеры сокращений приведены ниже в таблице:
Пример 1.1.2. Временем будем называть пару h: m, где h обозначает количество часов, а m – количество минут. Известно, что в h 1: m 1 начался дождь, а в h 2: m 2 он закончился (0 ≤ h 1, h 2 ≤ 23, 0 ≤ m 1, m 2 ≤ 59). Необходимо вычислить, сколько времени (hres: mres) шел дождь. Известно, что дождь продолжался не более 24 часов.
Если время h 1: m 1 больше чем h 2: m 2, то дождь начался в один день, а закончился на следющий. Например, если h 1: m 1 = 23:50 и h 2: m 2 = 13:20, то дождь длился 13 часов и 30 минут.
Времени h: m соответствует h *60 + m минут, прошедших с полночи. Тогда можно утверждать, что дождь начался в time 1 = h 1 * 60 + m 1 минут, а закончился в time 2 = h 2 * 60 + m 2 минут. Разность между началом и концом дождя составляет timeRes = (time 2 – time 1 + 24 * 60) % (24 * 60) минут. Выделяем количество часов и минут из timeRes и выводим их на экран.
#include < stdio.h >
int h1, h2, m1, m2, time1, time2, timeRes, hres, mres;
void main(void)
{
h1 = 23; m1 = 50; h2 = 13; m2 = 20;
time1 = h1 * 60 + m1; time2 = h2 * 60 + m2;
timeRes = (time2 - time1 + 24 * 60) % (24 * 60);
hres = timeRes / 60; mres = timeRes % 60;
printf("%d:%d\n",hres,mres);
}
Упражнение 1.1.1. Имеются одинаковые коробки, каждая из которых вмещает m шаров. Сколько коробок требуется для упаковки n шаров?
Упражнение 1.1.2. Рассмотрим условие предыдущей задачи. Сколько коробок будут полностью заполнены, если всего имеется n шаров, а каждая коробка вмещает m шаров?
Упражнение 1.1.3. Пусть n – трехзначное число. Присвоить переменным a, b, c соответственно количество сотен, десятков и единиц числа n.
УКАЗАНИЯ К РЕШЕНИЮ УПРАЖНЕНИЙ
Упражнение 1.1.1. Ответом будет значение выражения, которое на языке Си можно записать в виде (m + n – 1) / n.
Упражнение 1.1.2. Ответом будет значение выражения, которое на языке Си можно записать в виде m / n.
ЛОГИЧЕСКИЕ ОПЕРАЦИИ
Среди логических операций следует выделить операции 'и' ('and'), 'или' ('or'), отрицание 'не' ('not') и сложение по модулю 2 ('xor'). В языке Си логические операции обозначаются следующим образом:
Операция | Обозначение в Си |
x and y | x && y |
x or y | x || y |
not x | ! x |
x xor y | x ^ y |
Таблицы истинности логических операций приведены в следующих таблицах:
x | y | X and y | x | y | x or y | x | not x | x | y | x xor y | |||
Следует отметить также логическую операцию сравнения, обозначаемую в Си двумя знаками равенства. При этом выражение (x == y) эквивалентно!(x xor y). Операция называется операцией "сложение по модулю 2", потому что x xor y = (x + y) mod 2. Логические операции подчиняются правилу Де-Моргана:
not (x and y) = (not x) or (not y)
или то же самое!(x && y) =! x ||! y
Упражнение 1.2.1. Составить таблицу истинности следющих функций:
1. Равенства: x = y;
2. Импликации: x imp y = (not x) or y
Импликация — бинарная логическая связка. В булевой логике импликация — это функция двух переменных (они же — операнды операции, они же — аргументы функции). Переменные могут принимать значения из множества . Результат также принадлежит множеству
В классической логике условное утверждение имеет форму «Если А, то В». Оно ложно только в том случае, если А истинно, а В ложно, и истинно во всех остальных случаях. Содержание утверждений А и В при этом во внимание не принимается. Если даже они никак не связаны друг с другом по смыслу, составленное из них условное утверждение может быть истинным.