Смекни!
smekni.com

Язык прораммирования С++ (стр. 5 из 7)

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

2. Оператор цикла в форме for

Объявим целочисленную переменную I и рассмотрим оператор цикла на примере вывода на экран десяти чисел, кратных трем:

int I;

for(I=1;I<=10;I=I+1)

printf(“%d”,3*I);

Как и в Паскале, оператор состоит из:

– заголовкациклаfor(I=1;I<=10;I=I+1)

– многократно повторяемого тела цикла – оператора printf(“%d”,3*I).

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

Первое выражение I=1 выполнится один раз (до первого выполнения тела цикла) и определит начальное значение параметра цикла.

Перед каждым выполнением тела цикла вычисляется второе выражение (обычно там помещается проверка какого-то условия) и если условие не выполняется (значение выражения равно нулю), цикл завершается. Если условие выполнено (результат вычисления выражения не равен нулю), выполняется тело цикла.

После каждого выполнения тела цикла вычисляется третье выражение, которое обычно изменяет значение параметра цикла.

Как видим, в данном случае параметр I будет изменяться от одного до 10, при этом выводимое на экран значение 3*I, будет кратно трем. Результаты экзаменов показывают, что иногда у студентов вызывают затруднения даже такие простые задачи. Поэтому рассмотрим несколько похожих примеров.

1. Те же числа, но в обратном порядке можно вывести оператором

for(I=10;I;I=I-1)

printf(“%d”,3*I);

Оператор интересен тем, что вторым выражением является не проверка условия, а просто переменная I. Когда она станет равной нулю, цикл завершится.

2. Язык С++ предоставляет большую по сравнению с Паскалем свободу при реализации заголовка цикла. В частности, параметр цикла может быть вещественным числом, разрешено пропускать в заголовке цикла любое из выражений (а может, это называется записывать пустое выражение, потому что символы; пишутся обязательно). Следующий фрагмент показывает решение задачи с пропущенным первым выражением:

floatI=1;

for(;I<=10;I=I+1)

printf(“%f”,3*I);.

3. Можно пропустить также третье выражение и изменять переменную I втелецикла:

float I=1;

for(;I<=10;)

{I=I+1;

printf(“%d”,3*I);

}.

Как и в Паскале, циклически повторяется только один записанный после заголовка оператор. Если надо повторять несколько операторов, они объединяются фигурными скобками в блок. В данном случае

{

I=I+1;

Printf(“%d”,3*I);

} - это блок операторов. Блок языка С отличается от составного оператора Паскаля тем, что в блоке после открывающей фигурной скобки можно размещать объявления переменных. Такие переменные остаются видимыми только в пределах того блока, где они объявлены (с понятиями области видимости и времени жизни переменных мы знакомились при изучении Паскаля).

В отличие от С, язык С++ разрешает объявлять переменные в любом месте, кроме управляющих конструкций операторов. Например, нельзя объявлять переменную в условном операторе (в круглых скобках после if).

Но параметр цикла можно объявлять непосредственно в заголовке (хотя заголовок – это управляющая конструкция цикла):

for(int i=0; i<10;i=i+1) printf(“%d”,I);

При этом переменная i будет доступна не только в этом цикле, но и во всех последующих операторах до конца блока.

4. Если опустить в заголовке все три выражения, результат вычисления второго пустого выражения считается ненулевым и мы получаем бесконечный цикл. В этом случае для решения задачи можно применить оператор принудительного завершения оператора цикла - break:

intI=1;

for(;;) //Такой заголовок приводит к бесконечному повторению тела цикла.

{ if (I>10) break; //Выполнение оператора break вызывает завершение цикла

// и переход к следующему после цикла оператору.

I=I+1;

printf(“%d”,3*I);

}.

Знакомясь с оператором break языка Паскаль, мы отмечали, что его не было в авторской версии языка, его заимствовали из языка Си.

5. При решении данной задачи студенты часто пытаются в теле цикла дополнительно изменять значения I, чтобы они были кратны трем. В теле цикла при этом выводится значение I а не 3*I, например, так:

int I;

for(I=1;I<=10;I=I+1)

{ printf(“%d”, I);

I=I+3;}

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

Если не хочется применять длинную операцию умножения, цикл следует записать так: for(I=3;I<=30;I=I+3) printf(“%d”, I);.

6. Выведем на экран первые десять элементов последовательности

½,1/4, 1/6, 1/8...

Типичная ошибка при решении этой задачи приводит к выводу на экран значения 2-n. Элементы данной последовательности вычисляются оператором

floatI

for(I=1;I<10;I=I+1) printf(“%f”, 1/(2*I));

или, без использования умножения:

floatI, s=0;

for(I=1;I<10;I=I+1)

{ s=s+2;

printf(“%f”, 1/s);

}.

Чтобы выводить на экран значения 2-n, следует делить на 2 предыдущее вычисленное значение степени:

float I, s=1;

for(I=1;I<10;I=I+1)

{ s=s/2;

printf(“%f”, s);

}

Несколько замечаний по форматированию вывода

Предыдущий фрагмент выводит вычисленные значения степени одной строкой.

Запишем программу вывода значений 2-n полностью и будем выводить показатель и три варианта значения степени, использующие различные спецификации вывода

#include <stdio.h>

#include <conio.h>

int i;

float s=1;

void main(void)

{ clrscr();

for(i=1;i<20;i++)

{

printf("&bsol;n -%d cтепень &bsol;

равна %06.2f %6.2e %-6.3g ",i-1,s,s,s);

s=s/2;

}

getch();

}

При пуске программа выведет на экран следующий текст:

-0 cтепень равна 001.00 1.00e+00 1

-1 cтепень равна 000.50 5.00e-01 0.5

-2 cтепень равна 000.25 2.50e-01 0.25

-3 cтепень равна 000.12 1.25e-01 0.125

-4 cтепень равна 000.06 6.25e-02 0.0625

-5 cтепень равна 000.03 3.12e-02 0.0312

-6 cтепень равна 000.02 1.56e-02 0.0156

-7 cтепень равна 000.01 7.81e-03 0.00781

-8 cтепень равна 000.00 3.91e-03 0.00391

-9 cтепень равна 000.00 1.95e-03 0.00195

-10 cтепень равна 000.00 9.77e-04 0.000977

-11 cтепень равна 000.00 4.88e-04 0.000488

12 cтепень равна 000.00 2.44e-04 0.000244

-13 cтепень равна 000.00 1.22e-04 0.000122

-14 cтепень равна 000.00 6.10e-05 6.1e-05

-15 cтепень равна 000.00 3.05e-05 3.05e-05

Здесь каждое вычисленное значение выводится с новой строки. Мы знаем, что для перевода курсора на следующую строку на экран следует вывести символ с кодом 10, а для перемещения в начало строки – символ с кодом 13. Но у этих символов нет изображения, которое можно вставить текстовым редактором в выводимую строку. Если мы напишем printf(“10строка”), то в начале строки будут два символа ‘1’,’0’с кодами 49 и 48, а не символ перевода строки с кодом 10. Для включения в строку специальных символов в С++ используют букву, перед которой записан знак &bsol;. Например, &bsol;n понимается компилятором, как символ с кодом 10, &bsol;r – символ с кодом 13, &bsol;а – символ с кодом 7 (звонок) и т.д. Чтобы включить в строку знак &bsol;, его приходится записать дважды &bsol;. Из-за этого путь к файлу filename.dat, который находится в каталоге ABC, на языках С, С++ приходилось задавать так:

C:&bsol;ABC&bsol;filename.dat.

Таким образом, знак &bsol;n в программе вывода значений степени – это символ перевода строки.

Оператор вывода printf("&bsol;n -%dcтепень равна %06.2f%6.2e%-6.3g ",i-1,s,s,s); содержит очень много букв, поэтому он записан в две строки.

printf("&bsol;n -%d cтепень

равна%06.2f %6.2e %-6.3g ",i-1,s,s,s);

Для перехода в редакторе текста на новую строку мы нажимаем клавишу Enter, у нее тоже есть код, который вставляется в строку после слова «степень». Но этого кода не должно быть в строке, выводимой во время работы программы. Чтобы компилятор выбросил из строки код клавиши Enter, мы вводим &bsol;, а потом нажимаем Enter. (То есть, сочетание &bsol;<Enter > включает код перевода строки в исходный текст, но подавляет его в компилированной строке).

Вычисленная степень s выводится на экран три раза. Все три спецификации %f%gпредназначены для вывода вещественных чисел:

%f предписывает выводить число без множителя 10nс шестью знаками после десятичной точки, последняя цифра округляется;

%eпредписывает всегда выводить число в экспоненциальной форме (c множителем 10n);

%g сохраняет не больше шести значащих цифр результата (в %f шесть цифр только в дробной части, а здесь всего шесть, включая целую и дробную часть, но значащих цифр). Для очень маленького числа запишутся нули, а потом 6 цифр. Кроме того, в данном формате автоматически из двух вариантов представления числа – экспоненциального и с десятичной точкой, автоматически выбирается тот, который запишется короче.

В нашем примере после знака % перед буквой записаны цифры:

%6.2f означает, что на число (включая точку) отведено шесть позиций, из них две после точки. Если перед первым числом написать 0, %06.2f, в незаполненные старшие разряды запишутся нули (как в нашем примере);