Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Паппас К., Мюррей У. - Visual C++ 6. Руководство разработчика - 2000

.pdf
Скачиваний:
288
Добавлен:
13.08.2013
Размер:
4.96 Mб
Скачать

Глава 6. Инструкции

Инструкции выбора o Инструкция if

o Инструкция if/else

o Условный оператор ?: o Конструкция switch/case

Циклы

o Цикл for

o Цикл while

oЦикл do/while

Инструкции перехода

oИнструкция break

o Инструкция continue

o Инструкция return

Чтобы приступить к созданию первых программ на языках C/C++, вам следует познакомиться с некоторыми дополнительными средствами программирования. В этой главе будут рассмотрены базовые инструкции, составляющие основу любой программы. Большинство из них вам должно быть хорошо знакомо по другим языкам программирования высокого уровня.

Это такие инструкции, как if, if /else и switch/case, а также циклы for, while и do/while. В то же время ряд инструкций уникален для C/C++, например условный оператор ?:, ключевые слова break и continue. Они не имеют аналогов в более ранних языках программирования, таких как FORTRAN, COBOL или Pascal. По этой причине начинающие программисты часто оставляют их без внимания и не используют в своих программах. В результате остаются невостребованными некоторые уникальные возможности, предоставляемые языками C/C++. Кроме того, это выдает в вас новичка, которому вряд ли доверят работу над серьезным проектом.

Инструкции выбора

В языках C/C++ имеются четыре базовые инструкции выбора: if,if /else, switch/case и оператор ?:. Прежде чем приступить к изучению каждой из них, следует упомянуть об общих принципах построения условных выражений. Инструкции выбора используются для выборочного выполнения определенных блоков программы, состоящих либо из одной строки, либо из нескольких. В первом случае строка не выделяется фигурными скобками, во втором — выделяется весь блок.

Инструкция if

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

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

Обратите внимание, что условие заключается в круглые скобки. Если в результате проверки условия возвращается значение true, то выполняется выражение, после чего управление передается следующей строке программы. Если же результатом условия будет false, то выражение будет пропущено. Перейдем к конкретному примеру. В следующем фрагменте на экран выводится приветствие "Добрый день!" всякий раз, когда значение переменной ioutside_temp оказывается большим или равным 72:

91

if(ioutside_temp >= 72) printf("Добрыйдень!");

В более сложном случае, когда инструкция if охватывает несколько выполняемых команд, синтаксис немного меняется:

if(условие) {. выражение1; выражение2;

...

выражение-n; )

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

/*

*if.с

*В этой программе на языке С демонстрируется использование инструкции if.

*/

<stdio.h>

 

#include

 

int main ()

 

 

{

 

inum_Bs, inum_Cs;

 

int inum_As,

 

float

fGPA;

 

 

printf("\nВведите число предметов, по которым вы получили

оценку

ОТЛИЧНО:

");

&inum_As);

 

scanf("%d",

 

printf("\nВведите число предметов, по которым вы получили оценку ХОРОШО: ");

scanf("%d",&inum_Bs);

printf("\nВведите число предметов, по которым получили оценку УДОВЛЕТВОРИТЕЛЬНО: '") ;

scanf("%d",SinumCs);

fGPA = (inum_As*5 + inum_Bs*4 + inum_Cs*3)/(float)(inum_As + inum_Bs + inum_Cs);

printf("\nВаш средний балл: %5.2f\n",fGPA); if (fGPA >= 4.5){ printf("\nПОЗДРАВЛЯЕМ!\n");

printf ("\nВы прошли по конкурсу."); return(0); }

Обратите внимание, что инструкция if контролирует вывод только поздравительного сообщения, которое отображается, если значение переменной fGPA больше или равно 4,5.

Инструкция if/else

Инструкция if /else позволяет выборочно выполнять одно из двух действий в зависимости от условия. Ниже показан синтаксис данной инструкции:

if (условие) выражение1; else выражение2;

Если проверка условия дает результат true, то выполняется выражение1, в противном случае

— выражение2. Рассмотримпример:

if (ckeypressed — UP) iy_pixel_coord++; else iy_pixel_coord--;

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

92

Если операторная часть ветви if или else содержит не одно выражение, а несколько, необходимо заключать их в фигурные скобки, как показано в следующих примерах:

if(условие) { выражение1; выражение.?; выражениеЗ; } .

else

выражение 4;

if (условие) ( выражение1; else { выражение2; выражениеЗ; выражение4 ;

if (условие) { выражение1; выражение2; выражениеЗ;

}

else {

выражение 4; выражение5; выражение 6; }

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

В следующем примере демонстрируется использование инструкции if /else:

/*

*crapif.c

*В этой программе на языке С демонстрируется использование

*инструкции if /else.

*/

#include <stdio.h> int main ()

{

char c;

int ihow_many, i, imore; while (imore == 1) {

printf ("Введите название товара: "); if (scanf ("%c",&c)!= EOF)

{ while (c != '\n') scanf ("%c",&c) ; printf ("Сколько заказано? ");

scanf ("%d",&ihow_many) ; scanf ("%c",&c) ;

for(i= 1; i <= ihow_many; i++) printf ("*");

printf ("\n"); } else imore = 0 ;} return(0); }

Эта программа предлагает пользователю ввести название товара, и, если не получен признак конца файла [Ctrl+C] (EOF), то название будет прочитано буква за буквой, пока не встретится символ конца строки (генерируется при нажатии клавиши [Enter]). В следующей строке отобразится надпись "Сколько заказано?", после которой необходимо ввести число заказанных единиц товара. Затем в цикле for на экран выводится ряд звездочек, количество которых соответствует введенному числу. При обнаружении признака конца файла программный блок ветви if пропускается и выполняется строка программы в ветви else. В этой строке

93

устанавливается нулевое значение флага imore, что служит признаком завершения программы.

Вложенные инструкции if/else

Если используется несколько вложенных инструкций if, следует тщательно следить, какой из них соответствует ветвь else. Взгляните на следующий пример и попытайтесь определить порядок выполнения команд:

if(itemperature < 50) if(itemperature < 30) printf("Наденьте меховую куртку."); else printf("Наденьте шубу!");

В этом примере мы специально не делали отступов с помощью табуляции, чтобы не давать вам подсказок. Что произойдет, если значение переменной itemperature будет 55? Появится ли сообщение "Наденьте шубу!"? Конечно же, нет. В данном примере ветвь else связана со второй инструкцией if. Дело в том, что компилятор всегда связывает инструкцию else с ближайшей к ней несвязанной инструкцией if.

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

if(itemperature < 50) if (itemperature < 30)

printf ("Наденьте меховую куртку."); else printf("Наденьте шубу!");

Еще нагляднее следующая нотация:

if(itemperature < 50) if(itemperature < 30) printf("Наденьте меховую куртку."); else printf("Наденьте шубу!");

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

Рассмотрим пример:

if(условие1) if(условие2) выражение2; else выражение1 ;

Нетрудно заметить, что выделения отступами в этом примере ошибочны, и данный код ничем не отличается от предыдущего примера. Многие начинающие программисты часто пытаются устанавливать связи внутри блоков путем изменения отступов. Но ведь компилятор не учитывает отступы! Как же сделать так, чтобы выражение1 действительно было связано с условием1, а не условием2?

Чтобы исправить ошибку, необходимо использовать фигурные скобки:

if(условие1) { if (условие.2) выражение2;

}

else

выражение1;

С помощью фигурных скобок мы объединили условие2 и выражение2 в единый блок, выполняемый в том случае, если условие1 равно true. В результате ветвь else связывается с, первой, а не со второй инструкцией if.

Конструкция if/else/if

Конструкция if/else/if используется для того, чтобы последовательно проверить несколько условий. Ее синтаксис выглядит следующим образом:

94

if(условие!)

выражение1; else if(условие2) выражение2; else if (условие3) выражениеЗ;

Каждое выражение может представлять собой не одну строку, а блок команд. В таком случае требуются фигурные скобки (но помните, что после закрывающей фигурной скобки не ставится точка с запятой). В данном примере программа будет проверять условие за условием до тех пор, пока одно из них не возвратит значение true. Как только это произойдет, все остальные операторы else и связанные с ними действия будут пропущены. Если ни одно из условий не равно true, ни одно из действий не будет выполнено.

Теперь рассмотрим слегка видоизмененную версию предыдущего примера:

if(условие!)

выражение1; else if(условие2) выражение2; else if(условиеЗ) выражениеЗ; else действие_по_умолчанию;

В данном случае какое-то действие обязательно будет выполнено. Если ни одно из условий не равно true, выполняется действие_по_умолчанию. Чтобы понять, в каких случаях лучше применять эту конструкцию, рассмотрим следующий пример. Здесь переменная fconverted_value содержит значение длины в футах, а переменная econvert_to — признак преобразования. Если значение последней не соответствует ни одному из известных типов преобразования, отображается соответствующее сообщение.

if (econvert_to ==

YARDS)

 

 

fconverted_value =

length/3; else if

(econvert_to == INCHES)

fconverted_value =

length * 12; else

if (econvert_to ==

CENTIMETERS)

fconverted_value =

length * 30.48; else if (econvert_to

== METERS)

fconverted_value =

length * 30'. 48/100; else

 

printf ("Преобразование невозможно");

Условный оператор ?:

Оператор ? : позволяет создавать простые однострочные условные выражения, в которых выполняется одно из двух действий в зависимости от значения условия. Данный оператор можно использовать вместо инструкции if /else, а синтаксис его таков:

условие ? выражение1 : выражение2;

Оператор ? : называют тернарным, поскольку он требует наличия трех операндов. Рассмотрим пример, в котором определяется модуль числа:

if (f value >= 0.0) fvalue = fvalue; else fvalue = -fvalue;

С помощью условного оператора его можно записать в одну строку: fvalue = (fvalue >= 0.0)? fvalue : -fvalue;

В следующей программе на языке C++ условный оператор применяется для того, чтобы выбрать правильный вид выводимых данных:

//

//condit.cpp

//В этой программе на языке C++ демонстрируется использование

//условного оператора.

#include <math.h> #include <iostream.h> int main() <

float fbalance, fpayment;

cout << "Введите сумму заема: ";

95

cin >> fbalance;

cout << "\nВведите сумму погашения: "; cin >> fpayment;

cout << "\n\nВаш баланс: ";

cout << ((fpayment > fbalance) ? "переплачено на $" : "уплачено $"); cout << ((fpayment > fbalance) ? (fpayment - fbalance) : fpayment); cout << " по заему на сумму $" << fbalance << ".";

return(0);

Первый раз условный оператор используется для того, чтобы выяснить, какой текст выводить на экран: "переплачено на $" или "уплачено $". В следующем выражении с условным оператором определяется, какую денежную сумму следует отобразить:

cout << ((fpayment > fbalance) ? (fpayment - fbalance) : fpayment);

Конструкция switch/case

Часто возникает необходимость проверить переменную на равенство целому ряду значений. Это можно выполнить либо с помощью конструкции if/else/if, либо с помощью похожей конструкции switch/case. Обратим ваше внимание на то, что инструкция switch в языке С имеет ряд особенностей. Ее синтаксис таков:

switch(целочисленное_выражение) { , caseконстанта!:

выражение1; break;

саsе константа2: выражение2; break;

.

.

.

case константа-n: выражение-п; break;

default:

действие_по_умолчанию; }

Заметьте: инструкция break повторяется во всех ветвях, кроме самой последней. Если, скажем, из первой ветви удалить эту инструкцию, то после выражения1 будет выполняться выражение2, что не всегда желательно. Таким образом, инструкция break отвечает за то, что после выполнения одной из ветвей case все остальные ветви будут пропущены. Рассмотрим несколько примеров.

Предположим, имеется такой фрагмент:

if(emove == SMALL_CHANGE_DP)

fycoord = 5; else iftemove == SMALL_CHANGE_DOWN) fycoord = -5; else if(emove == LARGE_CHANGE_DP) fycoord = ,10;

else

fycoord = -10;

Его можно переписать с использованием инструкции switch:

switch(emove) {

case SMALL_CHANGE_UP: fycoord = 5;

break; case SMALL_CHANGE_DOWN: fycoord = -5;

break; case LARGE_CHANGE_UP: fycoord = 10;

96

break; default: fycoord = -10;

}

Здесь значение переменной emove последовательно сравнивается с рядом констант в ветвях case. Если обнаруживается совпадение, переменной fycoord присваивается нужное приращение. Затем выполняется инструкция break, которая передает управление строке, следующей после закрывающей фигурной скобки. Если же ни одно из сравнений не дало результата, то переменной fycoord присваивается значение по умолчанию (-10). Поскольку это последняя строка всего блока, нет необходимости ставить после нее инструкцию break. Следует также упомянуть о том, что ветвь default является необязательной.

Умелое манипулирование инструкциями break позволяет рациональнее строить блоки switch/case, как показано в следующем примере:

/*

*switch.с

*В этой программе на языке С демонстрируется, как рационально

*строить блоки switch/case.

*/

int main () { char с = 'a' ;

int ivowelct = 0, iconstantct = 0; switch(c)

{

case 'a' case 'A' case 'e' case 'E' case 'i' case 'I' case 'o' case '0' case 'u' case 'U' ivowelct++;

break; default : iconstantct++; return(0);

}

Если переменная с содержит ASCII-код любой гласной буквы, увеличивается счетчик гласных ivowelct, в противном случае осуществляется приращение счетчика согласных iconstantct.

Вдругих языках высокого уровня допускается объединение в одной проверке всех констант, приводящих к выполнению одного и того же действия. Но в C/C++ требуется, чтобы каждая константа была представлена отдельной ветвью case. Эффект объединения достигается за счет того, что связанные ветви не разделяются инструкциями break.

Вследующей программе на языке С инструкция switch используется для организации вызова правильной функции:

/*

*fnswitch.c

*В этой программе на языке С демонстрируются другие возможности

*инструкции switch.

*/

#include <stdio.h> #define QUIT 0 #define BLANK ' '

double

fadd(float fx,float fy) ;

97

double

fsub(float fx,float fy) ;

double

fmul(float fx,float fy) ;

double

fdiv(float fx,float fy) ;

int main() {

 

float fx, fy;

char cblank, coperator = BLANK;

while(coperator != QUIT) {

printf("\nВведите выражение вида (а (оператор) b): "); scanf("%f%c%c%f", &fx, &cblank, &coperator, &fy) ; switch (coperator) {

case '+':printf("ответ= %8.2f\n",fadd(fx, fy)); break; case '-':printf("ответ= %8.2f\n",fsub(fx, fy)); break; case '*':printf("ответ= %8.2f\n",fmul(fx, fy)); break; case '/':printf("ответ= %8.2f\n",fdiv(fx, fy)); break; case 'x': coperator = QUIT;

break;

default : printf("\nОператор не распознан.");}

}

return (0);

}

double fadd (float fx, float fy) { return (fx+ fy) ; }

double fsub (float fx, float fy) { return (fx - fy) ; }

double fmul (float fx, float fy) { return (fx* fy) ; }

double fdiv (float fx, float fy) { return (fx/ fy) ; }

Хотя синтаксис описания и вызова функций может быть еще непонятен вам (с функциями нам предстоит познакомиться в следующей главе), в целом использование инструкции switch в данном примере позволяет сделать текст программы максимально компактным и наглядным. Если пользователь введет какое-нибудь математическое выражение, скажем 10+10 или 23*15, соответствующий оператор (+ или *) будет сохранен в переменной coperator, значение которой затем сравнивается в блоке switch с набором стандартных арифметических операторов. Если же вместо арифметического оператора введен символ х, то программа присвоит переменной coperator значение quit, что является признаком завершения цикла, а с ним и всей программы.

Вслучае, когда пользователь случайно ввел какой-нибудь не распознаваемый программой символ, например %, управление передается ветви default, в которой на экран выводится предупреждающее сообщение.

Вязыке C++ инструкция switch используется аналогичным образом, в чем можно убедиться на следующем примере:

//

//calendar. Срр

//В этой программе на языке C++ демонстрируется использование

//инструкции switch для создания ежегодного календаря. #include <fstream.h>

int main() {

int jan_l_start_day, num_days_per_month, month, date, year; bool leap_year_flag;

ofstream fout("output.dat");

cout << "Укажите, на какой день недели приходится 1-е января\n"; cout << "\n(0— понедельник,";

cout << "\n 1 — вторник и т.д.): "; cin >> jan_l_start_day;

cout << "\nВведите год, для которого вы хотите построить календарь:”;

98

cin >> year;

fout << "\n Календарь на " << year << " год"; if(!(year % 4) && (year % 100) || !(year % 400)) leap_year_flag = true; else

leap_year_flag = false;

for(month = 1; month <= 12;month++) { switch(month) {

case 1:

cout << "\n\n\n Январь\n"; num_days_per_month = 31; break;

case 2:

cout << "\n\n\n Февраль\n"; num_days_per_month = leap_year_flag ? 29 : 28; break;

case 3:

cout << "\n\n\n Март\n"; num_days_per_month = 31;. break;

case 4:

cout << "\n\n\n Апрель\n"; num_days_per_month =30; break;

case 5:

cout << "\n\n\n Май\n"; num_days_per_month =31; break;

case 6:

cout << "\n\n\n Июнь\n"; num_days_per_month = 30; break;

case 7:

cout << "\n\n\n Июль\n"; num_days_per_month = 31; break;

case 8:

cout << "\n\n\n Август\n"; num_days__per_month = 31; break;

case 9:

cout << "\n\n\n Сентябрь\n"; num_days_per_month =30; break;

case 10:

cout << "\n\n\n Октябрь\n"; num_days_per_month = 31; break;

case 11:

cout << "\n\n\n Ноябрь\n"; num_days_per_month = 30; break;

case 12:

cout << "\n\n\n Декабрь\n";

99

num_days_per_month =31; break;

}

fout << "\nПон Вто Сре Чет Пят Суб Вос\n"; fout << " —-— —-— —-— —-— —-— —-— —-— \n";

for (date = 1; date < jan_l_start_day*4; date++) fout << " ";

for (date = 1; date <= num_days_per_month; date++) { fout.width.(3) ;

fout << date;

if ((date+ jan_l_start_day) % 7 > 0) fout << " ";

else

fout << "\n"; }

jan_l_start_day = (jan_l_start_day + num_days_per_month) % 7;

}

fout.close () ; return (0);

}

Программа начинает свою работу с того, что предлагает пользователю указать день недели, на который приходится 1-е января (0 соответствует понедельнику, 1 — вторнику и т.д.) Далее программа просит указать год, для которого вы. хотите построить календарь. Введенное значение отображается в виде заголовка календаря и сохраняется в переменной year. Выполнив ряд проверок, программа определяет, является ли введенный год високосным или нет, и сохраняет результат в переменной leap_year_flag (високосным является год, номер которого делится на 4, но не делится на 100, а также год, номер которого делится на 400).

Затем запускается цикл for, выполняющийся 12 раз — по одному разу для каждого месяца. Сначала выводится название месяца, а в переменную num_days_per_month записывается количество дней в данном месяце. Это осуществляется в блоке switch/case, состоящем из 12ти ветвей. Вслед за этим отображаются заголовки дней недели и в отдельной строке — ряд пробелов, чтобы начать выводить числа с того дня, на который приходится 1-е число данного месяца. В последнем цикле for выводятся собственно номера дней месяца. В последней строке внешнего цикла for вычисляется порядковый номер дня недели первого числа следующего месяца.

Совместное использование конструкций if/else/if и switch/case

В следующем примере выполняется преобразование имеющегося значения длины в футах в значение другой системы измерений:

/*

*ifelsw.c

*В этой программе на языке С демонстрируется использование

*конструкции if /else/if в сочетании с конструкцией switch/ case.

*/

#include <stdio.h>

enum conversion_type {YARDS, INCHES, CENTIMETERS, METERS} C_Tconversion;

int main()

{

int iuser_response;

float fmeasurement, ffoot;

 

printf("\nВведите значение

длины в футах: "); scanf("%f",&ffoot) ;

printf("\nВозможные единицы

измерений: \

\n\t\t0 - ЯРДЫ

\

 

\n\t\t1 – ДЮЙМЫ

\

 

\n\t\t2 - САНТИМЕТРЫ

\

 

100

Соседние файлы в предмете Программирование на C++