Лекция: Общее знакомство

Вид материалаЛекция

Содержание


Лекция 4. Операторы. Выражения
Простейшие выражения
Простейшие выражения
Составные операторы
Оператор цикла while
Изучение и использовании функций printf( ) и scanf( )
Применение функции scanf( )
Особенности работы с языком Си
Составной оператор
Составные операторы
5.Лекция: Преобразование типов
Подобный материал:
1   2   3   4   5   6   7   8   9   10   ...   33
^

Лекция 4. Операторы.

Выражения


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

100

1904 +100

a*(c-d)

x=0

x=y++

x>3

Выражениями называются компоненты программы, составленные с использованием операций, литералов, констант, переменных (включая массивы, структуры и объединения) и вызовов функций. Порядок вычисления выражений определен лишь требованиями соответствия семантике операторов и соблюдения правил приоритета и порядка выполнения операций. При выполнении этих требований компилятор свободен в выборе порядка вычисления выражения, даже если вычисление подвыражений может привести к побочным эффектам.

В отличие от большинства других языков, в языке Си для задания определенного порядка вычисления выражения недостаточно только соответствующей расстановки скобок, так как компилятор может произвольно переупорядочивать выражения, включающие ассоциативные и коммутативные операторы (*,+,|,^) даже при наличии скобок. Для задания желаемого порядка выполнения выражения нужно использовать дополнительные присваивания, если требуется, с использованием временных переменных.

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

j=3;

i=(k=j+1)+(j=5);

значение переменной i будет равно 9 или 11 в зависимости от того, какое подвыражение второй операции будет вычислено первым. Таким образом, с использованием разных компиляторов можно получить различные результаты.
^

Простейшие выражения


Простейшими выражениями называются выражения, сформированные с использованием констант типов int, char и enum, операции sizeof, унарных операторов - и ~, бинарных операторов + ~ * / % & | ^ << >> = = != < > <= >= и тернарной операции ?:.

^ Простейшие выражения используются в операторе switch, в инициализаторах границ массивов и в операторе препроцессора #if.

Логические операции ||, && являются условными логическими операциями, т. к. второй операнд вычисляется только при необходимости. В других языках программирования, например, в языке Паскаль, в логических операторах всегда вычисляются значения обоих операндов, даже если результат может быть определен вычислением одного операнда.

Важным свойством языка Си является то, что каждое выражение в Си имеет значение. Приведем несколько выражений и их значения:

Выражение

Значение

-14+16

2

a=3+8

11

5>3

1

14<3

0

6+(c=3+8)

17

Операторы


Любое выражение может быть преобразовано в оператор добавлением к нему точки с запятой. Запись вида

выражение;

является оператором. Значение выражения игнорируется. Действие такого оператора состоит в создании побочного эффекта вычислением значения выражения.

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

line = 5

- это всего лишь выражение, которое может быть частью большого выражения, но

line = 5;

является оператором.

Выражение

5+5

не является законченной инструкцией, а служит указанием компьютеру сложить 5 и 5, но не говорит, что делать с результатом.

dog=5+5;

служит указанием компилятору, а затем компьютеру, поместить результат 10 в ячейку памяти, помеченную именем dog. После занесения в память числа 10 компьютер может приступить к выполнению следующих действий.
^

Составные операторы


Составной оператор представляет собой два или более операторов, объединенных с помощью фигурных скобок; он называется также блоком. Чтобы быть свободным в обсуждении составных операторов, рассмотрим один из операторов цикла языка Си и использования в Си функций printf( ) и scanf( ).
^

Оператор цикла while


Пусть нам нужно каким-то образом заставить компьютер выполнять повторяющиеся вычисления. Язык Си предлагает несколько способов реализации повторяющихся вычислений. Сейчас мы коротко обсудим один из них. Данный способ называется "циклом с предусловием while". Цикл while работает следующим образом. Когда программа в процессе выполнения впервые достигает оператора while, осуществляется проверка истинности условия, заключенного в круглые скобки. Затем идет тело цикла, заключенное в фигурные скобки. В теле цикла перевычисляется переменная, которая анализируется в условии, там где встречается закрывающая фигурная скобка (конец тела цикла while), управление передается на оператор while. Если условие не выполняется, то управление передается за тело цикла, т.е. за закрывающую фигурную скобку.

Все операторы цикла языка Си рассматриваются в 8-ой лекции.

Пример 1:

/* От города А до города В расстояние равно 20 км.

Велосипедист выехал из А и в первый день проехал

10 км. В последующие дни он проезжал со скоростью,

на 0,5 раз большей, чем в предыдущий день. За сколько

дней велосипедист доберется до города В.*/

#include

#include

float km=10;

int d;

main()

{

clrscr(); /* чистка экрана, функция берется

из головного файла conio.h*/

d=1; /* первый день, за который велосипедист

проехал 10 км.*/

while(km<20) /* пока не выполнено условие цикла,

подсчитываются километры и дни*/

{

km+=(km*0.5);

d++;

}

printf("велосипедист был в пути %d дней",d);

getch();

}
^

Изучение и использовании функций printf( ) и scanf( )


Функции printf( ) и scanf( ) дают нам возможность взаимодействовать с программой. Мы называем их функциями ввода-вывода. Это не единственные функции, которыми мы можем воспользоваться для ввода и вывода данных с помощью программ на языке Си, но они наиболее универсальны. Эти функции не входят в описание языка Си. При работе с языком Си реализация функций ввода-вывода возлагается на создателей компилятора; это дает возможность более эффективно организовать ввод-вывод на некоторых машинах. Однако в интересах обеспечения совместимости различные системы имеют дело с некоторыми вариантами функций scanf( ) и printf( ). Обычно функции printf( ) и scanf( ) работают во многом одинаково - каждая использует управляющую строку и список аргументов. Сначала мы рассмотрим работу функции printf( ), затем scanf( ).

Формат

Тип выводимой информации

%d

десятичное целое число

%c

один символ

%s

строка символов

%e

экспоненциальная запись

%f

число с плавающей точкой, десятичная запись

%g

используется вместо записи %f или %e

%u

десятичное целое число без знака

%o

восьмеричное целое число без знака

%x

шестнадцатеричное целое число без знака

Инструкции, передаваемые функции printf( ), когда мы хотим напечатать некоторую переменную, зависят от того, какого типа эта переменная. Например, при выводе на печать целого числа применяется формат %d, а при выводе символа - %c. Форматы перечислены в таблице.

Посмотрим теперь, как эти формы применяются:

/* печать */

#define PI 3.14159

main( )

{

int number = 2003;

printf("Интернет-университет информационных

технологий был открыт в %d году \n", number);

printf("Значение числа pi равно %f.\n", PI);

}

Формат, указываемый при обращении к функции printf( ), выглядит следующим образом:

printf(Управляющая строка, аргумент1, аргумент2,_);

аргумент 1, аргумент 2 и т.д. - это печатаемые параметры, которые могут быть переменными, константами или даже выражениями, вычисляемыми перед выводом на печать.

Управляющая строка - строка символов, показывающая, как должны быть напечатаны параметры. Например, в операторе

printf("%d студентов получили оценку %f.\n",

number, z);

управляющей строкой служит фраза в кавычках, а number и z - аргументы или в данном случае значения двух переменных.

Мы видим, что в управляющей строке содержится информация двух различных типов:
  1. Символы, печатаемые текстуально.
  2. Идентификаторы данных, называемые также спецификациями преобразования.

Каждому аргументу из списка, следующего за управляющей строкой, должна соответствовать одна спецификация преобразования. Если нужно напечатать какую-нибудь фразу, то нет необходимости использовать спецификацию преобразования; если же требуется только вывести данные на печать, то можно обойтись и без использования комментария. Поэтому каждый из операторов, приведенных ниже, вполне приемлем:

printf("Эта книга не очень дорогая!\n");

printf("%c%d\n",'$',cost);

Если нужно напечатать сам символ %, то компилятор примет его за ошибочную спецификацию преобразования. Выходом из создавшейся ситуации служит довольно простое решение - писать два символа % подряд.

Например:

int i=2+3;

printf("Только %d%% населения способно учиться самостоятельно! \n",i);

Результат работы программы будет выглядеть следующим образом:

Только 5% населения способно учиться самостоятельно!

Мы можем расширить основное определение спецификации преобразования, поместив модификаторы между знаком % и символом, определяющим тип преобразования. При использовании одновременно нескольких модификаторов они должны быть указаны в том порядке, в котором перечислены в таблице.

Модификаторы

Значение

-

Аргумент будет печататься с левой позиции поля заданной ширины. Обычно печать аргумента оканчивается в самой правой позиции поля Пример: %-10

строка цифр

Задает минимальную ширину поля. Большее поле будет использоваться, если печатаемое число или строка не помещается в исходном поле Пример: %4d

строка цифр

Определяет точность: для типов данных с плавающей точкой число печатаемых цифр справа от десятичной точки; для символьных строк - максимальное число печатаемых символов Пример:

%4.2f (две десятичные цифры для поля шириной в четыре символа)

l

Соответствующий элемент данных имеет тип long, а не int Пример: %ld

Примеры:

main( )

{

printf("/%d/\n",135);

printf("/%2d/\n",135);

printf("/%10d/\n",135);

printf("/%-10d/\n",135);

}

Первая спецификация преобразования %d не содержит модификаторов. Это так называемый выбор по умолчанию, т. е. результат действия компилятора в случае, если вы не дали ему никаких дополнительных инструкций. Вторая спецификация преобразования - %2d. Она указывает, что ширина поля должна равняться 2, но, поскольку число состоит из трех цифр, поле автоматически расширяется до необходимого размера. Следующая спецификация %10d показывает, что ширина поля равна 10. Последняя спецификация %-10d также указывает ширину поля, равную 10, а знак - приводит к сдвигу всего числа к левому краю.
^

Применение функции scanf( )


Поскольку мы будем пользоваться функцией scanf( ) эпизодически, мы рассмотрим здесь только основные особенности ее применения. Для функции scanf( ) указывается управляющая строка и следующий за ней список аргументов. Основное различие функций printf( ) и scanf( ) заключается в особенностях данного списка. Функция printf( ) использует имена переменных, константы и выражения, а функция scanf( ) - только указатели на переменные. Мы ничего не должны знать о таких указателях. Необходимо помнить только два правила:
  1. Если нам нужно ввести некоторое значение и присвоить его переменной одного из основных типов, то перед именем переменной требуется писать символ &.
  2. Если мы хотим ввести значение строковой переменной, использовать символ & не нужно.

Пример:

main()

{

int age;

float assets;

char fio[50];

printf("Введите ваш возраст, оклад, фамилию. \n");

scanf("%d %f", &age, &assets);

scanf("%s", fio); /* & отсутствует при указании

массива символов */

printf("%d $%.0f %s\n",age, assets, fio);

}

Функция scanf( ) использует некоторые специальные знаки, пробелы, символы табуляции и "новая строка", для разбиения входного потока символов на отдельные поля. Она согласует последовательность спецификаций преобразования с последовательностью полей, опуская упомянутые специальные знаки между ними. Исключением является спецификация %c , обеспечивающая чтение каждого следующего символа даже в том случае, если это пустой символ.

Функция scanf( ) использует тот же набор символов спецификации преобразования, что и функция printf( ). Основные отличия функции scanf( ) следующие:
  1. Отсутствует спецификация %g.
  2. Спецификации %f и %e эквивалентны. Обе спецификации допускают наличие или отсутствие знака строки цифр с десятичной точкой или без нее и поля показателя степени.
  3. Для чтения целых чисел типа short применяется спецификация %h.

Функция scanf( ) не является одной из наиболее часто используемых функций языка Си. Мы обсуждаем ее из-за универсальности.

^ Особенности работы с языком Си. Задание фиксированной ширины полей оказывается полезным при печати данных столбиком.

Например:

printf("%d %d %5d\n",val1,val2, val3);

Результат выглядит так:

11 222 3333

4 5 23

22222 3332 11111

Эти же данные можно представить в улучшенном виде, если задать достаточно большую фиксированную ширину поля:

printf("%9d %9d %9d\n" val1,val2, val3);

Результат будет выглядеть так:

11 222 3333

4 5 23

22222 3332 11111

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

А теперь рассмотрим два примера работы с циклом while:

/*квадраты чисел*/

main( ) /*получение квадратов*/

{

int n=1;

while(n < 11) {

printf("%10d %10d\n", n, n*n);

n=n+1;

}

}

Эта программа выводит на печать первые 10 чисел и их квадраты.

Второй пример.

Согласно легенде, один правитель обещал наградить ученого, оказавшего ему большую услугу. Ученый, когда его спросили, что бы он хотел получить в награду, указал на шахматную доску и сказал: "Положите одно пшеничное зерно на первую клетку, два - на вторую, четыре на третью, восемь на следующую и т.д." Правитель был поражен, услышав такую скромную просьбу. Программа, приведенная ниже, показывает, в какое положение попал правитель!

/* пшеница*/

#define NUMBER 64 /* число клеток на шахматной доске*/

#define CROP 7E14 /* весь урожай пшеницы,

выраженный в числе зерен*/

main( )

{

double current, total;

int count =1;

printf("КЛЕТКА ЧИСЛО СУММА ЗЕРЕН ДОЛЯ\n");

total = current = 1.0;/*начинаем с одного зерна*/

printf("%4d %15.2e %13.2e %12.2e\n",count,

current, total, total/CROP);

while(count < NUMBER) {

count = count + 1;

current = 2.0*current;

/*удвоенное число зерен на следующей клетке */

total = total +current; /* коррекция суммы*/

printf ("%4d %15.2e %13.2e %12.2e\n",count,

current, total, total/CROP);

}

}

Это пример составного оператора. От открывающей фигурной скобки оператора while до закрывающей фигурной скобки.

Составной оператор используется в следующих случаях:
  1. Чтобы сгруппировать несколько логических связанных операторов в один оператор.
  2. В качестве тела функции.
  3. Для ограничения видимости определений частью программы, т.е. для локализации действия описаний.

^ Составной оператор имеет следующую форму:

{

определения и описания

операторы

}

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

!

Применяйте отступы от поля в строках, чтобы сделать структуру программы наглядной!

Подведем итог.

Выражение состоит из операций и операндов.

Оператор служит командой компилятору. Операторы бывают простыми и составными. Простые операторы оканчиваются символом "точка с запятой". Примеры:

Оператор описания:

int name;

Оператор присваивания:

current=12;

Оператор вызова функции:

printf("Текст\n");

Управляющий оператор:

while (n < 111) n=n+5;

Пустой оператор:

;

^ Составные операторы, или блоки, состоят из одного или более операторов, заключенных в фигурные скобки, которые в свою очередь сами могут быть составными.

Примеры:

/* Задача № 1.

Вычислить величину дохода по вкладу. Процентная

ставка (в процентах годовых), время хранения

(в днях) и сумма задаются во время работы программы.*/

#include

float р,t,s,d;

main()

{

puts("Введите сумму s");

scanf("%f",&s);

puts("Введите процентную ставку р");

/* вывод строки */

scanf{"%f",&p);

puts("Введите время хранения в днях t");

scanf("%f",&t);

d=p*s*t/36500;

printf("\n Величина дохода d=%f",d);

}


/* Задача № 2

По заданной стороне куба А определить его объем, площадь

грани и площадь поверхности.*/

#include

float a,v,s,si;

main()

{

puts("\n Введите сторону а");

scanf("%f",&a);

v=a*a*a;

s=a*a;

sl=s*6;

printf("\n объем v=%f",v);

printf("\n площадь грани s=%f",s);

printf("\n площадь поверхности sl=%f",sl);

}


/* Задача № 3

Определить реальное расстояние между населенными

пунктами. Указан масштаб карты и расстояние между

двумя точками, изображающими населенные пункты.*/

#include

float m,s,si;

main()

{

puts("Введите масштаб карты m");

scanf("%f",&m);

puts("Введите расстояние на карте si");

scanf("%f", &sl);

s=sl*m;

printf("\n реальное расстояние s=%f",s);

}

^ 5.Лекция: Преобразование типов