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

Нейбауер А. - Моя первая программа на С C++ - 2002

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

телю, что он ввел неправильное значение. Текст программы, в которой именно так и сделано, приведен в Листинге9.4.

Листинг 9.4. Программа, в которой используется флаг для отображения альтернативных сообщений.

/*flag.c*/

main()

{

int temp; float celsius; char repeat; char flag; do

{

flag = 'n'; do

{

if (flag == 'n');

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

температуры от 0 до 100: ");

else

printf("Вводи значение

правильно, дурак: ");

scanf("%d", &temp); flag = 'y';

}

while (temp < 0 || temp > 100)

celsius = (5.0 / 9.0) * (temp - 32); printf("%d градусов по Фаренгейту

соответствует %6.2f по Цельсию\n", temp, celsius); printf("Желаете продолжить ввод?"); repeat = getchar();

putchar('\n');

}

while (repeat == 'y' || repeat == 'Y');

}

Переменной с именем flag в начале каждого внешнего цикла присваивается значение 'n'. В начале каждого повтора внутреннего цикла значение флага проверяется. Если оно равно 'n', то программа выводит на экран одно сообщение, при любом другом значении флага на экран выводится второе сообщение.

При первом выполнении цикла флаг имеет значение 'n', поэтому на экран выводится первое сообщение. Когда пользователь вводит число, значение переменной меняется на 'y'. Однако если пользователь ввел неправильное значение, внутренний цикл снова повторяется, но в этом случае условие (flag == 'n') не выполнится, так что на экран будет выведено второе сообщение.

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

Ⱦɚɧɧɚɹ ɜɟɪɫɢɹ ɤɧɢɝɢ ɜɵɩɭɳɟɧɚ ɷɥɟɤɬɪɨɧɧɵɦ ɢɡɞɚɬɟɥɶɫɬɜɨɦ %RRNV VKRS Ɋɚɫɩɪɨɫɬɪɚɧɟɧɢɟ ɩɪɨɞɚɠɚ ɩɟɪɟɡɚɩɢɫɶ ɞɚɧɧɨɣ ɤɧɢɝɢ ɢɥɢ ɟɟ ɱɚɫɬɟɣ ɁȺɉɊȿɓȿɇɕ Ɉ ɜɫɟɯ ɧɚɪɭɲɟɧɢɹɯ ɩɪɨɫɶɛɚ ɫɨɨɛɳɚɬɶ ɩɨ ɚɞɪɟɫɭ piracy@books-shop.com

Хотя флаг и может быть определен с любым типом данных, рекомендуется все же выбирать для него тип int или char. Значения, присваиваемые флагу, также целиком определяет автор программы. В нашем примере использовалось значение 'n', чтобы отобразить правильный ввод данных, и 'y', чтобы отобразить неправильный ввод. Вы можете использовать любые другие значения, какие подскажет ваша фантазия.

Использование инструкции break

Использование флага несколько перегружает программу, так как требуется определение дополнительной переменной, введение нескольких строк для присваивания ей значения и лишняя конструкция if...else. Можно избежать этих сложностей и выполнить ту же работу, если применить цикл while. Пример такой программы приведен в Листинге9.5.

Листинг 9.5. Использование цикла while и инструкции break.

/*break*/

main()

{

int temp; float celsius;

printf("Введите значение температуры в пределах от 0 до 100.

Ввод значения 555 прекращает работу программы: "); scanf("%d", &temp);

while (temp != 555)

{

while ((temp < 0 || temp > 100)

&& temp != 555)

{

printf("Ошибка,

повторите ввод: ");

scanf("%d", &temp);

}

if (temp == 555) break; celsius=(5.0/9.0)*(temp-32);

printf("%d градусов по Фаренгейту соответствует %6.2f по Цельсию\n", temp, celsius);

printf("Значение введено, для прекращения работы наберите 555: ");

scanf("%d", &temp);

}

}

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

Считается, что при правильном вводе данных значения чисел лежат в промежутке от 0 до 100 или равны 555, причем ввод последнего немедленно прекращает работу программы, так как в ней записаны инструкции:

if (temp == 555) break;

www.books-shop.com

Инструкция break завершает цикл, в который она помещена, так же, как если бы условие while или условие цикла for перестало выполняться.

Все программы перевода значений температур из одной шкалы в другую, приведенные в этой главе, являются «правильными» программами. Во всех этих примерах мы применяли различный подход и использовали разные алгоритмы для выполнения одной и той же задачи. Если в программе присутствует запрос о необходимости прекращения работы, пользователю не надо помнить, какое именно специальное значение он должен ввести для прекращения работы, но зато при каждом повторе цикла он должен отвечать на дополнительный вопрос помимо ввода собственно значения температуры. Использование специальных значений, вроде числа 555 в нашем примере, избавляет от необходимости лишний раз нажимать на клавиши. Однако неудобство этого способа состоит в том, что нельзя использовать некоторые значения, которые могут оказаться корректными данными. Например, если прекращение работы программы происходит при вводе отрицательного значения, как тогда быть, если мы хотим преобразовать значения температуры ниже нуля?

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

Вопросы

1.Какими критериями вы будете руководствоваться при выборе цикла for, do или while?

2.Какие функции выполняют параметры for?

3.В каком случае прекращается выполнение цикла for?

4.Что такое вложенный цикл?

5.Как можно использовать флаг?

6.Каково назначение инструкции break?

Упражнения

1.Отредактируйте текст программы из Листинга 8.10 (глава 8) таким образом, чтобы она повторялась до тех пор, пока пользователь не пожелает прекратить ввод данных.

2.Напишите программу, которая рассчитывает сумму 6-процентного налога на продажи для товаров, имеющих стоимость в пределах от 1 до 50 долларов, и выводит информацию на экран монитора в виде таблицы

3.

Цена

Налог

Итого

4.

1

.06

1.06

 

2

.12

2.12

5.Напишите программу, которая вводит десять чисел в пределах от 0

до 25.

6.Напишите программу, которая выводит на дисплей следующий график:

7.* * * * *

8.* * * *

9.* * *

10.* *

11.*

12.* *

13.* * *

www.books-shop.com

14.* * * *

** * * *

15.Объясните, почему следующая программа написана неправильно:

16.main()

17.{

18.float row, column;

19.puts("\t\tТаблица Пифагора\n\n");

20.for (row = 1; row <= 10; row++)

21.

{

22.

for (column = 1;

23.column <= 10; column+)

24.printf("%d", row * column);

25.

}

26.

putchar('\n');

 

}

www.books-shop.com

ГЛАВА 10 МАССИВЫ И СТРОКИ

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

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

В этой главе рассказывается о том, как внести значения в специальную переменную, которая называется массивом (array). Кроме того, здесь подробно описывается работа со строковыми переменными.

Массивы

Представьте себе группу людей, стоящих в очереди, например, перед входом в кинотеатр. Единственная вещь, которая объединяет этих людей,— это то, что они стоят в одной очереди. Тот факт, что кто-то из них занимает первую позицию, не говорит нам ничего об этом человеке. У нас нет оснований думать, что он проворнее, выше, или богаче, чем любой другой из стоящих за ним.

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

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

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

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

Определение массива

Для определения массива необходимо указать типы значений, которые он содержит, и максимальное количество элементов, которое может быть в него записано. Синтаксис определения массива показан на рис.10.1. Для того чтобы создать массив, содержащий, например, 31 целое число, надо написать определение:

int temps[31];

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

При определении массива одновременно определяются и его отдельные элементы, как это показано на рис.10.2. К первому элементу массива temps обращаются как к temps[0], ко второму— как к temps[1], к третьему— как к temps[2] и так далее. Заметьте, что нумерация элементов массива начинается с 0, так что массив, состоящий из пяти элементов, показан на рисунке как массив, содержащий элементы с номерами от 0 до 4. Элемент с номером temp[5] не существует. Число, заключенное в квадратные скобки, называется индексом (subscript), и про элементы массива можно говорить как про «нулевой элемент массива temps», «первый элемент массива temps» и так далее.

www.books-shop.com

Рис. 10.1. Синтаксис определения массива

Рис. 10.2. При определении массива также определяютсяи составляющие его элементы

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

Определение строковой переменной на самом деле является определением массива символьных элементов:

char name[5];

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

Ввод значений в массив

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

int temps[5] = {45, 56, 12, 98, 12};

Таким образом, мы создали пять элементов, имеющих следующие значения: temps[0] 45

www.books-shop.com

temps[1] 56 temps[2] 12 temps[3] 98 temps[4] 12

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

int temps[5] = {45, 56, 12, 98, 12}; main()

{

static float prices[3] = {23.45, 34.56, 12.34};

Отдельным элементам массива можно присваивать значения внутри main() или другой функции, как в инструкции

temps[0] = 45;

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

main()

{

int temps[31]; int index;

for (index = 0; index 31; index++)

{

printf("Введите значение температуры #%d: ", index);

scanf("%d", &temp[index]);

}

}

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

Введите значение температуры #N

где N отображает индекс элемента, которому присваивается значение.

Обратите внимание, что количество повторов определяется увеличением значения переменной index от 0 до 30, а не до 31, поэтому данное значение может использоваться одновременно и как индекс для определения номера текущего элемента массива (которые пронумерованы от 0 до 30). Когда переменная index имеет значение 0, элемент temps[index] на самом деле является элементом temps[0]. Таким образом, значение, которое мы вводим в элемент temps[index] с помощью функции scanf(), присваивается первому элементу с именем temps[0]. С очередным выполнением цикла for значение переменной index возрастает, и при следующих повторах функция scanf() вводит значение в новые элементы массива. Этот процесс проиллюстрирован в табл.10.1.

Таблица 10.1. Использование цикла для увеличения индекса массива.

www.books-shop.com

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

Рис. 10.3. Разница между индексом и значением элемента массива

рис.10.3. Индекс элемента имеет значение 0, а переменная temps[0] равна75. Как мы уже поясняли это на примере очереди перед кинотеатром, значение индекса переменной не связано со значением переменной. Содержимое следующей переменной temps[1] может быть больше, меньше или равно значению пе-

ременной temps[0].

В том случае, когда значение элементу массива не было присвоено, он так же, как и любая переменная, будет иметь своим значением некий «мусор». Можно быстро инициализировать целочисленный массив, если в цикле присвоить его элементам нулевые начальные значения:

for (index = 0; index < 31; index++) temps[index] = 0;

Используя массив, можно ввести любое количество элементов, внеся соответствующие изменения в определение массива и условие цикла.

Работа с массивами

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

Значения, хранящиеся в массиве, можно использовать везде, где это может потребоваться в программе. Например, в Листинге10.1 приведен текст программы, в которой массив используется при выполнении двух различных задач. Во-первых, по элементам массива вычисляется среднее арифметическое значение, во-вторых, массив используется для перевода значений температуры из шкалы Фаренгейта в шкалу Цель-

www.books-shop.com

сия. Каждый раз, когда массив участвует в цикле for, значение переменной index возрастает от 0 до индекса последнего элемента массива.

Листинг 10.1. Использование массива для выполнения двух задач.

/*array1.c*/

main()

{

int temps[31]; int index, total;

float avarage, celsius; total = 0.0;

/*загрузка значений в массив*/ for (index = 0; index < 31; index++)

{

printf("Введите значение температуры #%d: ", index);

scanf("%d", &temp[index]);

}

/*подсчет среднего арифметического*/ for (index = 0; index < 31; index++)

total += temps[index]; average = total / 31.0; printf("Среднее значение

температуры составляет: %f\n\n", average); puts("Шкала Фаренгейта\t\tШкала Цельсия\n"); /*перевод значений в градусы Цельсия*/

for (index = 0; index < 31; index++)

{

celsius = (5.0/9.0)*(temps[index]-32); printf("%d\t\t%6.2f\n",

temps[index], celsius);

}

}

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

В программе, приведенной в Листинге 10.1, мы можем использовать любое количество элементов массива, вплоть до 31. Вместо цикла for предыдущей программы теперь используется цикл do...while, и инструкция

index = 0;

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

Листинг 10.2. Использование цикла do...while для загрузки массива.

/*array2.c*/

main()

{

www.books-shop.com

int temps[31]; int index, total;

float avarage, celsius, count; total = 0.0;

/*загрузка значений в массив*/

index = 0; do

{

printf("Введите значение температуры #%d, \ для прекращения введите 555: ", index);

scanf("%d", &temp[index]);

}

while (index < 31 && temps[index-1] != 555); /*подсчет среднего арифметического*/

index = 0; do

{

total += temps[index]; index++;

}

while (index < 31 && temps[index-1] != 555); count = index;

average = total / count; printf("Среднее значение

температуры составляет: %f\n\n", average); puts("Шкала Фаренгейта\t\tШкала Цельсия\n");

/*перевод значений в градусы Цельсия*/

index = 0; do

{

celsius = (5.0 / 9.0) * (temps[index] - 32); printf("%d\t\t%6.2f\n",

temps[index], celsius); index++;

}

while (index < 31 && temps[index-1] != 555);

}

В этой программе процедура ввода прекратится, когда окажутся введены значения всех элементов массива, или раньше, если вы введете значение флага 555, который проверяется в условии

while (index < 31 && temps[index-1] != 555);

Заметьте, что из значения переменной index в условии вычитается единица. Это сделано потому, что значение индекса увеличивается после ввода каждого числа. Если вы не хотите вводить значения во все элементы массива, введите после очередного значения температуры число 555, которое будет присвоено следующему элементу массива и прекратит выполнение цикла.

www.books-shop.com

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