Язык Си - руководство для начинающих - M. УЭИТ
Шрифт:
Интервал:
Закладка:
printf(" %d", 4 + 20);
на печать будет выведено число 24, а не выражение 4 + 20
Операнды могут быть как переменными, так и константами. Поэтому при выполнении оператора
income = salary + bribes;
компьютер возьмет значения двух переменных, стоящих в правой части, сложит их и присвоит затем полученную сумму переменной income.
Операция + называется "бинарной", или "диадической". Эти названия отражают тот факт, что она имеет дело с двумя операндами.
Операция вычитания: -
Выполнение операции вычитания приводит к вычитанию числа, расположеного справа от знака -, из числа, стоящего слева от этого знака. Оператор
takehome = 224.00 - 24.00;
присваивает переменной takehome значение 200.
Операция изменения знака: -
Знак минус используется также для указания или изменения алгебраического знака некоторой величины. Например, в результате выполнения последовательности операторов
rocky = -12;
smokey = -rocky;
переменной smokey будет присвоено значение 12.
Когда знак минус используется подобным образом, данная oneрация называется "унарной". Такое название указывает на то, что она имеет дело только с одним операндом.
РИС. 5.2. Унарные и бинарные операции
Операция умножения: *
Операция умножения обозначается знаком *. При выполнении оператора
cm = 2.54 * in;
значение переменной in умножается на 2.54, и результат присваивается переменной cm.
Вы хотите иметь таблицу квадратов натуральных чисел? В языке Си нет функции, осуществляющей возведение в квадрат; вместо этого мы можем использовать умножение.
/* квадраты чисел */
main( ) /* получение таблицы квадратов */
{
int num = 1;
while(num < 21) {
printf("%10d %10d", n, n*n);
n = n + 1;
}
Эта программа выводит на печать первые 20 целых чисел и их квадраты, в чем вы сами легко можете убедиться. Теперь давайте рассмотрим более интересный пример. Вы, наверное, слышали историю о том, как один могущественный правитель обещал наградить ученого, оказавшего ему большую услугу. Ученый, когда его спросили, что бы он хотел получить в награду, указал на шахматную доску и промолвил: "Положите одно пшеничное зерно на первую клетку, два - на вторую, четыре на третью, восемь на следующую и т. д.". Правитель, которому явно недоставало математической эрудиции, был поражен, услышав такую скромную просьбу,- ведь он уже приготовил богатые дары. Программа, приведенная ниже, показывает, в какое смешное положение попал правитель. В ней вычисляется количество зерен, которое надо положить на каждую клетку, а также промежуточные результаты (суммы зерен по числу клеток). Поскольку вы, возможно, не знакомы с урожаями пшеницы, мы, кроме того, сравниваем промежуточные суммы зерен с приблизительными цифрами годового урожая пшеницы в США.
/* пшеница */
#define SQUARES 64 /* число клеток на шахматной доске */
#define CROP 7E14 /* урожай пшеницы в США, выраженный в числе зерен */
main( ) {
double current, total, int count = 1;
printf(" клетка число зерен сумма зерен доляn");
printf("от урожая в СШАn"),
total = current = 1.0; /* начинаем с одного зерна */
printf("%4d %15.2е%13.2е%12.2en", count, current, total, total/CROP);
while (count < SQUARES){
count = count + 1;
current =2.0 * current; /* у двоение числа зерен на следующей клетке*/
total = total + current; /* коррекциясуммы*/
printf(" %4d %15.2е%13.2е%12 2en" , count, current, total, total/CROP); }
}
Вначале результаты работы программы выглядят довольно безобидно.
На первых 10 клетках оказалось чуть более тысячи зерен пшеницы. Но давайте посмотрим, сколько зерен на пятидесяти клетках.
Добыча ученого превысила весь годовой урожай пшеницы в США. Если вы захотите узнать, что окажется на 64 клетках, выполните программу сами.
Этот пример иллюстрирует феномен экспоненциального роста возрастание населения земного шара и использование нами энергетических ресурсов подчиняются тому же закону.
Операция деления: /
В языке Си символ / указывает на операцию деления. Величина, стоящая слева от этого знака, делится на величину, расположенную справа от него. Например, в результате выполнения оператора:
four = 12.0/3.0;
переменной four будет присвоено значение 4.0. Заметим, что над данными целого типа операция деления производится не так, как над данными с плавающей точкой в первом случае результат будет целым числом, а во втором - числом с плавающей точкой. У целого числа нет дробной части, что делает деление 5 на 3 затруднительным, поскольку результат не является целым. В языке Си принято правило, согласно которому дробная часть у результата деления целых чисел oтбрасывается. Это действие называется "усечением".
Попробуйте выполнить приведенную ниже программу, чтобы посмотреть, как осуществляется усечение результата и чем деление чисел отличается от деления чисел с плавающей точкой.
/*Примеры деления */
main()
{
printf(" деление целых: 5/4 это %d n" , 5/4);
printf(" деление целых 6/3 это %d п" , 6/3);
printf(" деление целых 7/4 это %d п" , 7/4);
printf(" деление чисел с плавающей точкой 7 /4 это %2.2f n", 7 /4 );
printf(" смешанное деление 7 /4 это %2.2f n" , 7 /4);
}
Мы включили в нашу программу также случай "смешанных" типов, осуществляя деление вещественного числа на целое. Язык Си менее строго "подходит" к подобным вопросам, чем некоторые другие языки, и позволяет выполнять такие операции, но, вообще говоря, смещения типов следует избегать. Вот результаты выполнения указанной программы. Обратите внимание на то, что результат деления целых чисел округляется не до ближайшего целого, а всегда до меньшего целого числа. Когда мы смешиваем целые числа и числа с плавающей точкой, результат будет таким же, как если бы оба операнда были числами с плавающей точкой, поскольку в этом случае перед делением целое преобразуется в число с плавающей точкой.
Указанные свойства операции деления целых чисел оказываются довольно удобными при решении некоторых задач. Очень скоро мы приведем соответствующий пример. Нам осталось рассмотреть еще один важный вопрос, что происходит в тех случаях, когда в одном операторе используется несколько операций? Это и послужило нам темой обсуждения, приведенного ниже.
Порядок выполнения операций
Рассмотрим следующую строку:
butter = 25.0 + 60.0 * n / SCALE;
В этом операторе имеются операции сложения, умножения и деления. Какая операция будет выполнена первой? Будет ли 25.0 складываться с 60.0, затем результат 85.0 умножаться на n, а произведение делиться на значение константы SCALE? Или 60.0 умножается на n, результат складывается с 25.0, а сумма затем делится на величину SCALE? Или же существует какой-то другой порядок выполнения операций? Пусть переменная n равна 6.0, а константа SCALE - 2.0. Если вы выполните данные операции, используя эти значения, вы найдете, что при первом способе вычисления результат равен 255, а при втором - 192.5. При выполнении данной Си программы на машине реализуется, по-видимому, какой-то другой порядок вычислений, поскольку на деле переменная butter получит значение 205.0.
Совершенно очевидно, что изменение порядка выполнения действий может приводить к различным результатам, поэтому язык Си нуждается в наборе непротиворечивых правил, указывающих, какое действие осуществлять первым. Язык Си делает это, задавая приоритет той или иной операции. Каждой операции назначается уровень старшинства. Умножение и деление имеют более высокий уровень, чем сложение и вычитание, поэтому они выполняются первыми. Если же две операции имеют один и тот же уровень старшинства, они выполняются в том порядке, в котором присутствуют в операторе. Для большинства операций обычный порядок - слева направо. (Операция = является исключением из этого правила.) Поэтому в операторе
butter = 25.0 + 60.0 * n / SCALE;