6 - Томский политехнический университет

advertisement
МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ
Федеральное государственное бюджетное образовательное учреждение высшего
профессионального образования
«НАЦИОНАЛЬНЫЙ ИССЛЕДОВАТЕЛЬСКИЙ ТОМСКИЙ
ПОЛИТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ»
Учебно-методические указания к
лабораторной работе №6 по курсу «Информатика»
Разработка программы нахождения максимального или минимального элементов
в массиве
Томск 2012 г.
СОДЕРЖАНИЕ
ВВЕДЕНИЕ
3
Основные операции, операторы ветвления и циклов
4
1.1
Арифметические выражения
4
1.2
Логические выражения
5
1.3
Приоритеты (порядок) выполнения операций
6
1.4
Порядок вычислений
7
1.5
Выбор вариантов
7
1
1.5.1
Условные операторы
8
1.5.1.1 Оператор ветвления (проверки условия) if
8
1.5.1.2 Операция условия
10
1.5.1.3 Множественный выбор: оператор switch
11
1.5.2
Операторы циклов
12
1.5.2.1 Оператор цикла while
13
1.5.2.2 Оператор цикла for
15
1.5.2.3 Оператор цикла do while
16
1.5.2.4 Вложенные циклы
17
1.5.3
Другие управляющие операторы
18
1.5.3.1 Оператор break
19
1.5.3.2 Оператор continue
19
1.5.3.3 Оператор goto
19
2
Организация ввода элементов массивов
20
3
Задача поиска минимального (максимального) значения
20
2
ВВЕДЕНИЕ
Данные учебно-методические указания содержат теоретический материал
необходимый для выполнения лабораторной работы №6 «Разработка программы
нахождения максимального или минимального элементов в массиве» по курсу
Информатика для бакалавров направления 140800 «Ядерные физика и технологии». В
частности, рассматриваются основные операции, операторы ветвления и циклов, задача
поиска минимального (максимального) элемента в массиве.
3
1 Основные операции, операторы ветвления и циклов
Арифметические выражения
1.1
Аналогом математической формулы в языке Си, как и в других языках
программирования, является арифметическое выражение. Оно может содержать
числовые константы, переменные, вызовы функций, знаки арифметических операций и
круглые скобки.
Основными операциями в Си являются:
=
операция присваивания
*
операция умножения
/
операция деления
+
операция сложения
–
операция вычитания или операция изменения знака
Дополнительные операции:
1) % – операция деления по модулю, использующаяся в целочисленной
арифметике. Результат – остаток от деления. Например, при вычислении 13 % 5
получим 3, так как 13=2*5+3.
2) +=, –-=, *=, /=, %= – дополнительные операции присваивания, корректирующие
значения
переменной,
стоящей
слева
от
знака
присваивания.
Переменной
присваивается новое значение, равное старому, скорректированному с помощью
величины выражения, стоящего справа. Результат зависит от используемой операции.
Например:
scor += 20; – то же самое, что scor = scor + 20;
dim *= 3*scor + 5; – то же самое, что dim = dim*(3*scor+5);
Эти формы записи более компактны и позволяют при трансляции получить более
эффективный машинный код.
3) ++ и -- – операции увеличения и уменьшения для целочисленных данных. Они
увеличивают (уменьшают) значение своего операнда на 1. Например: операция a++
аналогична операции a=a+1.
Отличия арифметического выражения от формулы состоят в следующем:
1. Арифметическое выражение записывается линейно, т.е. в строку. Например,
формуле
x
b
соответствует выражение x/b.
2. Порядок
действий
однозначно
определен
в
записи
арифметического
выражения, в то время как производить вычисления по одной и той же математической
4
формуле можно разными способами. Например, вычислить значение
a b
cd
можно
разными способами (1: вычислить a.b, затем c.d и разделить первый результат на
второй; 2: вычислить a/c, затем b/d и умножить первый результат на второй; 3:
вычислить b/d, разделить на с и умножить на а и т.д.). Но арифметическому выражению
a*b/(c*d) соответствует только способ 1; если более предпочтителен способ 3, то
арифметическое выражение будет выглядеть по-другому: b/d/c*a.
3. Из всех видов скобок используются только круглые. Например: формула
a{b+c[d+e(f+g)]} будет записана в виде a*(b+c*(d+e*(f+g))).
4. Запрещено ставить подряд два знака арифметических операций. Например,
недопустима запись 3*-2. В подобных случаях надо использовать скобки: 3*(-2).
5. Нельзя опускать знак умножения между сомножителями. Например: ba – это
имя переменной, а b*a – это арифметическое выражение.
1.2
Логические выражения
Операции отношения используются для сравнений и применяются при
формировании выражений условия ("логических выражений"). При программировании
на Си используются:
<
меньше
<=
меньше или равно
==
равно
>=
больше или равно
>
больше
!=
не равно
С помощью этих операций величина слева от знака операции сравнивается с
величиной справа от него:
a<b
c >= 0
Результатом вычисления операции отношения будет 0 ("ложь") или 1 ("истина").
Более того, в качестве "истины" принимается любое значение, не равное 0!
Не путайте оператор присваивания (=) и операцию отношения "равно" (= =)! Это
совершенно разные действия:
cnn = 3;
– присваивает значение 3 переменной cnn;
cnn = = 3;
– проверяет, равняется ли значение переменной cnn числу 3.
5
Простое логическое выражение состоит из знака операции отношения и
операндов, расположенных слева и справа от него. Однако иногда (и довольно часто)
требуется объединить два или более простых логических выражения. Для этого в языке
Си имеются три логические операции:
Операция
Смысл
И
&&
||
ИЛИ
НЕ
!
Предположим, что expr1 и expr2 – два простых логических выражения типа cat >
rat или debt == 1000. Тогда
1. expr1 && expr2 истинно в том и только в том случае, когда оба выражения
expr1 и expr2 истинны.
2. expr1 || expr2 истинно в том случае, если какое-нибудь из выражений expr1
или expr2 истинно или оба истинны.
3. !expr1 истинно, если выражение expr1 ложно, и наоборот.
Примеры:
5 > 2 && 4 > 7 – ложно, поскольку истинно только одно подвыражение;
5 > 2 || 4 > 7 – истинно, поскольку по крайней мере одно из подвыражений
истинно;
!( 4 > 7 ) – истинно, потому что 4 не больше 7. Это выражение эквивалентно
обратному условию: 4 <= 7
Математическое двойное неравенство a  c < d на языке Си будет выглядеть
следующим образом:
a <= c && c < d
1.3
Приоритеты (порядок) выполнения операций
Операция ! имеет очень высокий приоритет, он выше, чем у умножения, такой же,
как у операции увеличения, и только круглые скобки имеют более высокий приоритет.
Приоритет операции && выше, чем операции ||, а обе они имеют более низкий
приоритет, чем операции отношения, но более высокий, чем операция присваивания.
Поэтому выражение
a > b && b > c || b > d
будет интерпретировано так:
((a > b) && (b > c)) || (b > d)
т.е. b содержится между с и а или b больше d.
6
Список операций по старшинству
(от высокого приоритета к низкому)
!, ++,- -, -, & (адрес), * (указатель)
*, /, %
+, <, <=, >, >=
= =, !=
&&
| |
?:
=, +=, -=, *=, /=
1.4
Порядок вычислений
Логические выражения вычисляются слева направо; вычисления прекращаются,
как только устанавливается истинность или ложность всего выражения. Пример:
num != 0
&&
10/num == 1
Если значение переменной num равно 0, то все выражение ложно, и поэтому
дальнейшее вычисление данного логического выражения прекращается. Это избавляет
компьютер от последствий деления на нуль. Многие языки не обеспечивают
выполнения подобного требования, и, выяснив, что num равно 0, компьютер переходит
к проверке следующего условия, что скорее всего приведет к ошибке.
1.5
Выбор вариантов
Согласно теории вычислительных систем, хороший язык должен обеспечивать
реализацию следующих трех форм управления процессом выполнения программ:
1. Выполнение последовательности операторов.
2. Выполнение определенной последовательности операторов до тех пор, пока
некоторое условие истинно. Операторы циклов и безусловного перехода позволяют
реализовать данную форму управления.
3. Использование проверки истинности условия для выбора между различными
возможными способами действия. Операторы условия ("ветвления") if и выбора
вариантов switch позволяют реализовать третью форму управления.
Обычно операторы в программе выполняются в том порядке, в котором они
написаны. Однако, используя операторы передачи управления, можно передать
управление в другую точку этой же программы. Операторы передачи управления
7
можно также использовать для управления итеративным процессом, задержкой
выполнения программы и окончанием программы.
Применение всех трех форм позволяет создавать мощные, универсальные и
полезные программы. Совместно с операторами ветвления и цикла могут быть
использованы операторы перехода и прерывания цикла.
1.5.1
Условные операторы
Условные операторы дают программисту возможность передавать управление
на тот или иной оператор программы в зависимости от определенных условий. То есть
если проверяется какое-то условие, результатом которого является “истина” или
“ложь”, то, очевидно, в зависимости от результата должны выполняться различные
действия.
1.5.1.1 Оператор ветвления (проверки условия) if
С помощью оператора ветвления if можно осуществит выбор из двух
возможностей – выполнить набор действий или пропустить его, либо осуществить
выбор одного из двух вариантов.
Этот оператор имеет следующие структуры:
1) Простейшая форма оператора позволяет выбрать оператор или пропустить его
(рисунок 1):
выражение
нет
да
if (выражение)
оператор;
оператор
Рисунок 1
Под "выражением" (или условием) здесь обычно понимают логическое
выражение; если такое выражение истинно, то "оператор" выполняется, в противном
случае он пропускается. Вообще говоря, в качестве условия может быть использовано
любое выражение, и если его значение равно 0, то оно считается ложным. "Оператор"
может быть простым или составным, состоящим из нескольких операторов. Если в
"оператор" на самом деле входит несколько операторов, то они объединяются в блок
с помощью фигурных скобок.
8
Примеры:
if ( x > y ) printf(" Мы победили!\n");
if ( n < 10 )
{
y = x – 1;
n++;
}
2) Конструкция if – else позволяет выбрать одно из двух действий (рисунок 2):
if (выражение)
оператор1;
else
оператор2;
выражение
нет
да
оператор 1
оператор 2
Рисунок 2
Если "выражение" истинно, то выполняется "оператор 1", если ложно, то
выполняется "оператор 2".
Примеры:
if ( x > y )
else
printf (" Мы победили!\n");
printf (" Мы проиграли!\n");
if ( n < 10 )
{
y = x – 1;
n++;
}
else
y = z;
3) Конструкция else – if, являющаяся расширением конструкции if – else,
позволяет осуществлять выбор более чем из двух вариантов (рисунок 3).
if (выражение1)
оператор1;
else if (выражение2)
оператор2;
else
оператор3;
выражение 1
да
нет
выражение 2
нет
оператор 1
да
оператор 3
оператор 2
Рисунок 3
Если "выражение 1" истинно, то выполняется "оператор 1". Если "выражение 1"
ложно, но "выражение 2" истинно, выполняется "оператор 2". В случае, когда оба
выражения ложны, выполняется "оператор 3".
9
Фактически конструкция else – if является видоизмененным способом задания
оператора ветвления, описанного выше. По-другому эту структуру можно описать:
if (выражение1)
оператор1
else
if (выражение2)
оператор2
else
оператор3
Видно, что она состоит из оператора if – else, для которого часть else представляет
собой другой оператор if – else. Про второй оператор if – else говорят, что он "вложен"
в первый.
В одном операторе можно использовать столько конструкций else – if, сколько
нужно, что иллюстрируется ниже:
if ( score < 1000 )
bonus = 0;
else if ( score < 1500 )
bonus = 1;
else if ( score < 2500 )
bonus = 2;
else
bonus = 10;
Не забывайте, что else соответствует ближайшему if, кроме тех случаев,
когда имеются фигурные скобки.
1.5.1.2 Операция условия
В языке Си имеется короткий способ записи одного из видов оператора if-else. Он
называется "условным выражением" и использует операцию условия ?: .
Эта операция состоит из двух частей и содержит три операнда. Пример оператора,
с помощью которого находится абсолютное значение числа:
x = (y < 0) ? (-y) : y;
Все, что находится между знаком "=" и символом "точка с запятой", представляет
собой условное выражение. Смысл этого оператора заключается в следующем: если y
меньше 0, то x=(-y); в противном случае x=y. В терминах оператора if-else данный
оператор мог выглядеть так:
if (y < 0) x = -y; else x = y;
В общем виде условное выражение можно записать следующим образом:
10
выражение1 ? выражение2 : выражение3
Если "выражение1" истинно, то значением всего условного выражения является
величина "выражения2"; в противном случае значение всего условного выражения –
величина "выражения3".
1.5.1.3 Множественный выбор: оператор switch
Если в программе необходимо произвести выбор одного из нескольких вариантов,
то удобнее применять оператор switch.
Общая структура оператора:
switch (целое выражение)
{ case метка1:
операторы; (необязательные)
break; (необязательный)
case метка2:
операторы; (необязательные)
break; (необязательный)
default: (необязательный)
операторы; (необязательные)
}
Вначале вычисляется выражение в скобках, расположенное за ключевым словом
switch. Затем программа просматривает список "меток" до тех пор, пока не находит
"метку", соответствующую данному значению. Далее программа переходит к
выполнению оператора, расположенного в этой строке. Если такой подходящей метки
не найдется, то если существует строка с "меткой" default , то будет выполняться
оператор, помеченный этой меткой. В противном случае произойдет переход к
оператору, расположенному за оператором switch. Выполнение оператора break
приводит к тому, что в программе происходит выход из оператора switch и
осуществляется переход к следующему за ним оператору. При отсутствии оператора
break будут выполнены все операторы, начиная с помеченного данной меткой до
конца оператора switch. Метки, имеющиеся в операторе switch, должны быть
константами или константными выражениями (выражение, операторы которого
константы) целого типа (включая тип char). Запрещается использовать в качестве
метки переменную. Значением выражения в скобках должна быть величина целого
типа.
11
1.5.2
Операторы циклов
Циклом называется последовательность операторов, которая выполняется
несколько раз в процессе выполнения программы при различных значениях некоторой
переменной или при выполнении какого-то условия. Например, необходимо вычислить
среднее значение последовательности а0, а1, а2, … а10.
В этом случае в программе можно написать следующее:
float a[10], sum, sr;
sum = 0;
sum = sum + a[0];
sum = sum + a[1];
. . .
sum = sum + a[9];
sr = sum/10;
Собственно для подсчета суммы необходимо написать 10 операторов
присваивания, имеющих одинаковый вид и отличающихся только индексами текущих
элементов массива. А что делать, если длина последовательности не 10, а 100? Или
конкретное количество обрабатываемых элементов вводится пользователем уже в ходе
выполнения вашей программы? В последнем случае просто неизвестно заранее,
сколько операторов присваивания нужно выполнить. В этом случае на помощь и
приходит такой инструмент, как цикл.
В
этом
случае
алгоритм
для
расчета
суммы
первых
N
элементов
последовательности А и вычисления затем среднего значения можно записать
следующим образом:
1. Задаём начальное значение для суммы, равное нулю (СУММА = 0).
2. Задаем начальный номер элемента массива, например, 1 (ИНДЕКС = 1).
3. К сумме добавляем значение элемента массива с номером ИНДЕКС (СУММА
= СУММА + А[ИНДЕКС]).
4. Увеличиваем ИНДЕКС на 1 (ИНДЕКС = ИНДЕКС + 1).
5. Проверяем, не вышли ли за пределы массива (ИНДЕКС<=N ?).
6. В случае результата “истина” возвращаемся к п.№3, в случае результата “ложь”
переходим к следующему пункту (в нашем случае №7).
7. Вычисляем среднее (СРЕДНЕЕ = СУММА / N).
Блок-схема алгоритма приведена на рисунке 4.
12
СУММА=0
ИНДЕКС = 1
СУММА = СУММА+
А[ИНДЕКС])
ИНДЕКС =
ИНДЕКС + 1
да
ИНДЕКСN
нет
Рисунок 4 – Алгоритм расчета суммы последовательности А длиной N
Повторяющиеся действия (п.3, 4, 5) и будут выполняться циклически.
В языке Си реализовано три вида циклов: while(), for() и do ... while(). С учетом
этого, вместо приведенного выше примера можно привести следующие варианты
реализации:
С использованием
оператора for()
С использованием
оператора while()
sum = 0;
i = 0; sum = 0;
for (i=0; i<n; while ( i < n )
i++)
{
{
sum
=
sum
sum
=
sum
+ a[i];
a[i];
i++;
}
}
sr = sum/10;
sr = sum/10;
С использованием
С использованием
оператора do... while() операторов if и goto
i = 0; sum = 0;
i = 0; sum = 0;
do
m:
{
sum = sum +
+ sum
=
sum
+ a[i];
a[i];
i++;
i++;
if ( i < n )
}
goto m;
while ( i < n ); sr = sum/10;
sr = sum/10;
1.5.2.1 Оператор цикла while
Структура оператора (рисунок 5):
выражение
нет
да
while (выражение)
оператор;
оператор
Рисунок 5
Оператор while определяет операции, которые циклически выполняются до тех
пор, пока проверяемое "выражение" не станет ложным, или равным нулю, т.е. если
"выражение" истинно (или а общем случае не равно нулю), то "оператор" (или "тело
цикла") выполняется один раз, а затем "выражение" проверяется снова. Эта
последовательность действий, состоящая из проверки и выполнения тела цикла,
периодически выполняется до тех пор, пока "выражение" не станет ложным. Каждый
такой шаг называется "итерация".
13
Оператор while – это цикл с предусловием; решение, выполнять ли в очередной
раз тело цикла, принимается перед началом его прохождения. Поэтому вполне
возможно, что тело цикла не будет выполнено ни разу. "Оператор", образующий тело
цикла, может быть либо простым (одиночным, заканчивающимся символом "точка с
запятой"), либо составным, тогда группа составляющих его операторов заключается в
фигурные скобки.
Примеры:
while ( n++ < 100 )
printf(" %d %d \n",n,2*n+1);
int far = 0, step = 2;
while ( far < 1000 )
{
far = far + step;
printf(" far = %d\n", far);
}
Не забудьте о том, что при построении цикла while вы должны включить в него
какие-то конструкции, изменяющие величину проверяемого выражения так, чтобы в
конце концов оно стало ложным. В противном случае выполнение цикла никогда не
завершится.
При организации цикла, когда его тело должно быть выполнено фиксированное
число раз, осуществляются три операции: инициализация счетчика, сравнение его
величины с некоторым граничным значением и увеличение значения счетчика при
каждом прохождении тела цикла, причем инициализация счетчика для цикла while
должна осуществиться до цикла (см. второй пример), о чем случайно можно забыть.
14
1.5.2.2 Оператор цикла for
Структура оператора:
Иниц.; Усл.; Корр.
инициализация
for
(инициализация;
проверка
условия; коррекция)
оператор;
условие
нет
оператор
да
оператор
коррекция
Рисунок 6
В операторе for используются три выражения, управляющие работой цикла; они
разделены символами "точка с запятой". Инициализирующее выражение вычисляется
только один раз до начала выполнения какого-нибудь из операторов цикла. Если
проверяемое выражение оказывается истинным (или не равным нулю), тело цикла
выполняется один раз. Затем вычисляется величина корректируемого выражения, и
значение проверяемого выражения определяется вновь. Таким образом, тело цикла
выполняется до тех пор, пока проверяемое условие не станет ложным, или равным
нулю. В виде блок-схемы порядок этих действий отображен на рис.Error! Reference
source not found..
Оператор for – это цикл с предусловием: решение, выполнить в очередной раз
тело цикла или нет, принимается до начала его прохождения. Поэтому может случиться
так, что тело цикла не будет выполнено ни разу. Оператор, образующий тело цикла,
может быть как простым, так и составным.
Примеры:
for ( n=0; n < 10; n++)
printf(" %d %d \n",n,2*n+1);
В "инициализации" и "коррекции" могут находиться несколько операций,
разделяемых между собой запятыми. Например:
for (sum = 0.0, x = 1.0, count = 1; count <= 10; count++, x
*= 2.0)
{
sum += 1.0/x;
printf(" sum = %f ,когда count = %d\n", sum, count);
}
В заголовке цикла for ни одно из трех выражений не является обязательным,
однако два символа "точка с запятой" обязаны присутствовать.
Ниже приведено описание "вечного" цикла для ввода любого символа и вывода
его и его кода на экран:
15
char c;
for ( ; ; )
{
printf("Введите любой символ: ");
scanf("%s",&c);
printf("Симовол = %c; его код = %d\n", n, n);
if ( c == 'q' ) break;
// break – оператор выхода
из цикла
}
Выход из цикла осуществляется, если введен символ 'q'. По-другому то же самое
можно было записать так:
char c='a';
for ( ; c != 'q'; )
{
printf("Введите любой символ: ");
scanf("%s",&c);
printf("Симовол = %c; его код = %d\n", n, n);
}
Цикл for очень удобно использовать при работе с массивами. Пример:
float
g[10], f[10];
int
i;
for (i = 0; i < 10; i++)
{
printf("Введите %d-ый элемент массива: ", i);
scanf("%f",&g[i]);
printf("g[%d] = %f\n", i, g[i]);
f[i] = 2 * g[i];
}
Здесь организован ввод и вывод десяти элементов вещественного одномерного
массива g и заполнение соответствующих элементов массива f по формуле fi = 2gi.
ВНИМАНИЕ!!!
Как
известно,
символ
";"
используется
там,
где
соответствующий оператор ЗАКАНЧИВАЕТСЯ, поэтому фрагмент
for (i = 0; i < 10; i++);
//
№1
{
printf("Введите %d-ый элемент массива: ", i);
scanf("%f",&g[i]);
printf("g[%d] = %f\n", , g[i]);
f[i] = 2 * g[i];
// №2
}
не является правильным: так как сразу после заголовка цикла (№1) стоит символ
окончания оператора, то к моменту, когда начнёт выполняться оператор
(№2),
параметр i уже примет "плохое" значение 10, и повторений тела цикла никаких не
будет (ведь собственно цикл уже закончился!!!).
1.5.2.3 Оператор цикла do while
Структура оператора:
16
оператор
do
оператор
while (выражение);
да
выражение
нет
Рисунок 7
Оператор do while определяет действия, которые циклически выполняются до
тех пор,
пока проверяемое выражение не станет ложным, или равным нулю (см.
рис.Error! Reference source not found.). Оператор do while – это цикл с постусловием;
решением, выполнять или нет в очередной раз тело цикла, принимается после его
прохождения. Поэтому тело цикла будет выполнено по крайней мере один раз.
Оператор, образующий тело цикла, может быть как простым, так и составным.
Пример 1:
do{
printf("Введите любой символ: ");
scanf("%s",&c);
printf("Симовол = %c; его код = %d\n", n, n);
} while ( c != 'q' );
В этом примере выполняется абсолютно то же самое, что и в приведенном выше
для организации ввода символов.
Пример 2:
do{
printf("Введите количество строк в массиве (1..5): ");
scanf("%d",&m);
} while ( m<1 || m>5 );
Здесь в качестве "условия" проверяется значение, введенное в качестве количества
строк матрицы. В случае истинности, что на самом деле означает, что число введено
неправильное, количество строк запрашивается вновь.
1.5.2.4 Вложенные циклы
Так как "оператор" во всех приведенных выше конструкциях может быть
составным, то внутри него можно использовать и другой цикл, и операторы ветвления,
и т.д.
Вложенным называется цикл, находящийся внутри другого цикла (рисунок 8).
17
Внешний
цикл
in1=0; in1< m; i n1=in1+1
in2=0; in2< n; in2=in2 +1
Вну тренний
цикл
Тело
внешнего
цикла
Тело
внутреннего
(вложенно го)
цикла
Рисунок 8 – Изображение на блок-схеме вложенных циклов
При работе с двумерными массивами, для перебора всех элементов массива
(например, он описан как double mm[razm1][razm2]), очень удобно пользоваться
приведенной ниже конструкцией. Здесь цикл с параметром ind1 является внешним, в
котором задается текущий номер строки в массиве mm, а цикл с параметром ind2 –
внутренним, в котором задается текущий номер столбца. Таким образом, каждое
сочетание ind1 и ind2 позволяет обратиться к каждому элементу массива:
for (ind1=0; ind1 < razm1; ind1++)
{
for (ind2=0; ind2 < razm2; ind2++)
{
... – операторы, использующие соответствующий элемент массива; например:
mm[ind1][ind2] = Pi * (ind1+ind2);
}
}
a = mm[ind1][ind2]; /* – неправильно, т.к. оба цикла уже закончились, и оба
индекса уже приняли "плохое" значение. */
1.5.3
Другие управляющие операторы
Операторы, рассматриваемые ниже, обычно используются реже, поскольку
слишком частое их использование ухудшает читаемость программы, увеличивает
вероятность ошибок и затрудняет ее модификацию.
Выполнение каждого из этих трех операторов языка вызывает скачкообразное
изменение процесса выполнения программы, т.е. переход от одной команды
программы к другой (не следующей за ней непосредственно).
18
1.5.3.1 Оператор break
Оператор break можно использовать внутри любой из трех форм цикла и
конструкции switch. Его выполнение приводит к тому, что управление программой,
минуя оставшуюся часть тела цикла или конструкцию switch, содержащую данный
оператор, передается на следующую (за этим циклом или за конструкцией switch)
команду.
Пример:
switch (number)
{
case 4: printf("Это хороший выбор.\n");
break;
case 5: printf("Это неплохой выбор.\n");
break;
default: printf("Это плохой выбор.\n");
}
1.5.3.2 Оператор continue
Оператор continue может использоваться в любой из трех форм цикла, но не в
операторе switch. Его выполнение приводит к такому изменению логики программы,
что остальные операторы тела цикла пропускаются. Для циклов for или while вслед за
этим начинается новый шаг, а для цикла do while проверяется условие на выходе, и
затем, если оно оказывается истинным, выполняется следующая итерация.
Пример:
for ( i=0; i<n; i++)
{
if ( i==j ) continue;
x[i] = i*i;
a = a + x[i]*3;
}
Здесь в теле цикла по параметру i проверяется условие равенства значения i
значению переменной j, и в случае истинности проверки остальные два оператора тела
цикла пропускаются.
1.5.3.3 Оператор goto
Выполнение оператора goto вызывает передачу управления в программе
оператору,
помеченному
указанной
меткой.
Для
отделения
оператора
от
соответствующей ему метки используется двоеточие. Имена меток образуются по тем
же правилам, что и имена переменных. Помеченный оператор может появиться в
тексте программы до или после goto.
Пример:
19
mm: printf("Введите количество строк матрицы (от 1 до 10): ");
scanf("%d",&n);
if ( n<1 || n>10 ) {printf("Неверно! Еще раз!\n"); goto mm;}
В приведенном примере в том случае, когда введено "плохое" значение
переменной n, выдается сообщение, и управление опять передается на вывод
приглашения к вводу значения.
Не стоит употреблять оператор goto, если на это нет веских причин, т.к. это, вопервых, может привести к ошибкам в ходе выполнения, если вы перепутаете метки, а
во-вторых, портит структуру вашей программы. Н а самом деле можно привести еще
много причин, но ограничимся пока этими двумя.
2 Организация ввода элементов массивов
Не забывайте, что в качестве индекса элемента массива можно использовать не
только целые константы, но и переменные целого типа. Допустим, имеется массив,
описанный как float a[20][30], в который значения надо ввести с клавиатуры.
Так как при вводе надо обратиться к КАЖДОМУ элементу массива, т.е. перебрать все
сочетания номеров строк и номеров столбцов, то можно организовать ввод, используя
вложенные циклы:
for ( i=0; i<20; i++ )
for ( j=0; j<30; j++ )
scanf("%f", &a[i][j]);
Если в текущий момент необходимо обрабатывать не все 20 строк, а n (где n20),
то нужно использовать эту переменную (не забудьте её предварительно задать – с
помощью оператора присваивания или использовав функцию ввода):
for ( i=0; i<n; i++ )
for ( j=0; j<30; j++ )
scanf("%f", &a[i][j]);
и т.д.
3 Задача поиска минимального (максимального) значения
Задача поиска минимального элемента из числового ряда может быть решена с
помощью описанных выше операторов. С этой целью можно ввести дополнительную
переменную, которой присваивается значение первого элемента числового ряда. Затем,
сравнивая последовательно значение этой переменной со значением всех элементов
числового ряда, находят минимальный элемент (рисунок 9).
20
smin=d0
i=1
нет
i<10
да
smin>di
да
нет
smin=di
i = i+1
Рисунок 9 – Блок-схема поиска минимального элемента
Пример (здесь приведен поиск минимального значения в целочисленном
одномерном массиве d из 10 элементов):
int d[10], i, smin;
...
smin = d[0];
i = 1;
while( i<10 )
{
if( smin > d[i] )
{
smin = d[i];
}
i++;
}
...
Или другой вариант реализации данного алгоритма:
int d[10], i, smin;
...
smin = d[0];
for(i=1; i<10; i++)
{
if( smin > d[i] )
{
smin = d[i];
}
}
...
21
Download