Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ИТ11зт / лекции СИ.doc
Скачиваний:
19
Добавлен:
11.06.2015
Размер:
588.8 Кб
Скачать

2.2. Элементарные средства программирования

Деление операторов языка Си на группы.

Вернемся вновь к структуре простой программы, состоящей только из одной функции с именем main( ).

директивы препроцессора

void main( )

{ определения_объектов;

исполняемые операторы;

}

В качестве определяемых объектов будем вводить переменные и константы базовых типов.

Каждый исполняемый оператор определяет действия программы на очередном шаге ее выполнения. У оператора (в отличие от выражения) нет значения. По характеру действий различают два типа операторов: операторы преобразования данных и операторы управления работой программы.

Наиболее типичные операторы преобразования данных - операторы присваивания и произвольные выражения, завершенные символом "точка с запятой”:

i++; /*Арифметическое выражение - оператор*/

x*=i; /*Оператор составного присваивания*/

i=x-4*i; /*Оператор простого присваивания*/

Так как вызов функции является выражением с операцией "круглые скобки" и операндами "имя функции", "список фактических параметров", к операторам преобразования данных можно отнести и оператор вызова или обращения к функции:

имя функции (список_фактических параметров);

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

Операторы управления работой программы называют управляющими конструкциями программы. К ним относятся:

• составные операторы;

• операторы выбора;

• операторы циклов;

• операторы перехода.

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

{

n++;

summa+=(float)n )

}

а этот фрагмент - блок:

{

int n=0;

n++;

summa+=(float)n;

}

Наиболее часто блок употребляется в качестве тела функции.

Операторы выбора - это условный оператор (if) и переключатель (switch).

Операторы циклов в языке Си трех видов - с предусловием (while), с постусловием (do) и параметрический (for).

Операторы перехода выполняют безусловную передачу управления: goto (безусловный переход), continue (завершение текущей итерации цикла), break (выход из цикла или переключателя), return (возврат из функции).

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

Условный оператор имеет сокращенную форму:

if (выражение_условие) оператор;

где в качестве выражения_условия могут использоваться: арифметическое выражение, отношение и логическое выражение. Оператор, включенный в условный, выполняется только в случае истинности (т.е. при ненулевом значении) выраж-ния_условия. Пример:

if (х < 0 && х > -10) х=-х:

Кроме сокращенной формы, имеется еще и полная форма условного оператора:

if (выражение_условие)

оператор _1;

else

оператор _2;

Здесь в случае истинности выражения-условия выполняется только оператор_1, при нулевом значении выражения-условия выполняется только оператор_2. Например:

if (x > 0)

b=х ;

else

b=-х;

Оператор в сокращенном варианте оператора if, и оператор_1 и оператор 2 в полном операторе if могут быть как отдельными, так и составными операторами.

Например, при решении алгебраического уравнения 2-й степени ax2+bx+c=0 действительные корни имеются только в случае, если дискриминант (b2~4ас) неотрицателен. Следующий фрагмент программы иллюстрирует использование условного оператора при определении действительных корней х1, х2 квадратного уравнения:

...............

d=b*b - 4*а*с; /* d - дискриминант */

if (d>=0.0)

{

xl=(-b+sqrt(d))/2/a;

х2=(-b-sqrt(d))/2/а;

printf("\n Корни: xl=%e, x2=%e", xl, х2);

}

else

printf("\n Действительные корни отсутствуют.");

Во фрагменте предполагается, что переменные d, b, a, xl, х2 - вещественные (типа float либо double). До приведенных операторов переменные а, b, с получили конкретные значения, для которых выполняются вычисления. В условном операторе после if находится составной оператор, после else - только один оператор - вызов функции printf(). При вычислении корней используется библиотечная функция sqrt() из стандартной библиотеки компилятора. Ее прототип находится в заголовочном файле math.h.

Метки и пустой оператор. Метка - это идентификатор, помещаемый слева от оператора и отделенный от него двоеточием ":". Например,

СОН: Х+=-8;

Чтобы можно было поставить метку в любом месте программы (или задать пустое тело цикла), в язык Си введен пустой оператор, изображаемый только одним символом ";". Таким образом, можно записать такой помеченный пустой оператор:

МЕТКА:;

Оператор перехода. Оператор безусловного перехода имеет

следующий вид:

goto идентификатор;

где идентификатор - одна из меток программы. Например: goto СОН; или goto МЕТКА;

Ввод данных. Для ввода данных с клавиатуры ЭВМ в программе будем использовать функцию (описана в заголовочном файле stdio.h):

scanf {форматная_строка, список_аргументов);

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

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

% * ширина_поля модификатор спецификатор

Среди элементов спецификации преобразования обязательны только % и спецификатор. Для ввода числовых данных используются спецификаторы:

d - для целых десятичных чисел (тип int);

u - для целых десятичных чисел без знака (тип unsigned int);

f - для вещественных чисел (тип float);

е - для вещественных чисел (тип float).

Ширина_поля - целое положительное число, позволяющее определить, какое количество байтов (символов) из входного потока соответствует вводимому значению.

В качестве модификаторов используются символы:

h - для ввода значений типа short int (hd);

l - для ввода значений типа long int (ld) или double (lf, le);

L - для ввода значений типа long double (Lf, Le).

В отличие от функции printf() аргументами для функции scanf( ) могут быть только адреса объектов программы, в частном случае - адреса ее переменных. Не расшифровывая понятие адреса (адресам и указателям будут рассмотрены позже), напомним, что в языке Си имеется специальная унарная операция & получения адреса объекта:

& имя_обьекта

Выражение для получения адреса переменной будет таким:

& имя_переменной

Итак, для обозначения адреса перед именем переменной записывают символ &. Если name - имя переменной, то &name -ее адрес.

Например, для ввода с клавиатуры значений переменных n, z, х можно записать оператор:

scanf ("%d%f%f",&n,&z,&x);

В данном примере спецификации преобразования в форматной строке не содержат сведений о размерах полей и точностях вводимых значений. Это разрешено и очень удобно при вводе данных, диапазон значений которых определен не строго. Если переменная n описана как целая, z и х - как вещественные типа float, то после чтения с клавиатуры последовательности символов 18 18 -0.431 переменная n получит значение 18, z — значение 18.0, х-значение -0.431.

При чтении входных данных функция scanf() воспринимает в качестве разделителей полей данных "обобщенные пробельные символы" - собственно пробелы, символы табуляции, символы новых строк.

Пример: Вычисление объема цилиндра.

/*Вычисление объема прямого цилиндра*/

#include <stdio.h>

void main( )

{

double h, r, v;

const float PI = 3.14159;

/*h - высота цилиндра, r -радиус цилиндра*/

/*v - объем цилиндра, PI - число "пи" */

printf("\n Радиус цилиндра r= ");

scanf("%lf", &r);

printf("Высота цилиндра h= "); ;

scanf("%lf”, &h);

v = h * PI * r * r;

printf("Объем цилиндра: %10.4f" ,v):

}

В тексте программы несколько особенностей. Определена константа PI, т.е. со значением 3.14159 связано имя PI, которое до конца выполнения программы будет именовать только это значение.

Перед каждым вводом помещены вызовы функции printf( ), выводящей на экран запрос-подсказку, вслед за которой на экране отображается набираемое на клавиатуре вводимое значение. Функция scanf() считывает только это значение, как только будет нажата клавиша "Ввод" (Enter), что воспринимается как признак конца строки ввода. Поэтому очередной вызов функции printf( ) выводит данные на следующую строку. Обратите внимание на спецификации преобразования %lf Если бы переменные h и r имели тип float, то в форматных строках функций scanf() нужно было бы применять спецификации %f или %е. Текст на экране при выполнении программы может быть таким:

радиус цилиндра r= 2.0

высота цилиндра h= 4.0

объем цилиндра: 50.2654

Здесь пользователь ввел 2.0 для г и 4.0 для h. Другой вариант:

радиус цилиндра r= 4.0

высота цилиндра h= 2.0

объем цилиндра: 100.5309

Еще раз обратите внимание на использование в функции scanf() не имен переменных, а их адресов &r, &h.

Сумма членов ряда Фибоначчи. Ряд Фибоначчи определен, если известны первые два его члена f1, f2, так как очередной член fi =fi-1 + fi-2 для r>2. Необходимо вычислить сумму заданного количества (k) первых членов ряда Фибоначчи, если известны первые два: р = F1 и r = F2. Следующая программа решает эту задачу:

/*Вычисление суммы членов ряда Фибоначчи*/

#include <stdio.h>

void main( )

{

int k,i;/*к-число членов; i-номер члена */

float s,p,r,f; /* s - искомая сумма */

/*Члены: р -первый; r - второй; f - i-й*/

Ml: printf("\n Введите число членов ряда k=") ;

scanf ("%d",&k) ;

if( k > 2 ) goto M2;

printf("\n Ошибка! k должно быть > 2 !");

goto Ml;

M2: printf("\n Первый член ряда р=") ;

scanf("%f",&p);

printf("\n Второй член ряда r=");

scanf("%fn,&r);

i = 3;

s = p + r;

M: f = p + r;

s = s + f;

p = r;

r = f ;

i = i + 1;

if ( i <= k ) goto M;

printf("\n Сумма членов ряда: %10.3f", s);

}

Обратите внимание на строки, где выполняется проверка введенного значения k. Программа может правильно работать только при к>2, поэтому только в этом случае выполняется переход к метке М2. В противном случае печатается сообщение об ошибке, и после перехода к метке Ml запрашивается новое значение k.

Особенность и недостаток программы состоят в том, что она никогда не закончит вычислений, если не ввести допустимого значения к>2.

Соседние файлы в папке ИТ11зт