В окне программы вместо русских букв выводятся какие-то странные символы

Эта проблема объясняется различием таблиц кодировок Windows и DOS. В этих таблицах

русские буквы расположены в разных местах. Консольные программы при работе исполь-

зуют кодировку DOS, а текстовый редактор Visual C++ – кодировку Windows. Поэтому

вам придется добавить преобразование строк с русскими буквами из кодировки Windows

в кодировку DOS.

Для этого включите в программу, после файла iostream.h, файл windows.h с описа-

нием функций операционной системы Windows:

#include <windows.h>

Перед функцией main() создайте новую функцию с именем rus_str(), которая будет вы-

полнять необходимое преобразование с помощью специальной функции Windows:

char* rus_str(char* str)

{

CharToOem(str, str);

return str;

}

Во всех строках программы, где на экран выдаются символьные строки с русскими бук-

вами, укажите преобразование этих строк с помощью новой функции, например:

cout << rus_str("Введите текущий год и нажмите ENTER.\n");

После завершения работы окно программы закрывается и не удается увидеть ре-

Зультаты.

Для исправления этого недостатка проще всего предусмотреть в конце программы ввод

произвольного символа. Пока пользователь не нажмет какую-нибудь символьную клави-

шу и потом Enter, окно программы будет оставаться на экране. Для этого потребуется за-

вести символьную переменную (строку с описанием этой переменной расположите после

строки с описанием целочисленных переменных):

char wait_char;

Перед строкой с оператором возврата "return 0" добавьте оператор для ввода символа

с клавиатуры:

cin >> wait_char;

Сравните результаты работы своей программы с примером из лекции. Поэкс-

периментируйте над улучшением или изменением формата вывода на экран.

Упражнение 2

Модифицируйте программу 5.1, чтобы при превышении переменной

"another_age" значения 150 на экран выводилось сообщение:

Извините, но вы вряд ли доживете до [year] года!

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

Упражнение 3

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

На экран программа должна выводить следующие сообщения:

Введите текущий год и нажмите ENTER.

2000

Введите текущий месяц (число от 1 до 12).

10

17

Введите свой возраст (в годах).

25

Введите месяц своего рождения (число от 1 до 12).

5

Введите год, для которого вы хотите узнать свой возраст.

2006

Введите месяц этого года.

6

Ваш возраст в 6/2006: 31 год и 1 месяц.

Программа должна выдавать корректные сообщения для единственного и мно-

жественного числа лет и месяцев, т.е. должна выводить на экран "25 лет и 1 ме-

сяц", но "24 года и 2 месяца".

Подсказка: В программе вам потребуются дополнительные переменные. Обязатель-

но добавьте их имена в оператор описания переменных. При вычислениях могут при-

годиться некоторые стандартные операции Си++:

Символ Операция Пример Значение

+ Сложение 3 + 5 8

- Вычитание 43 - 25 18

* Умножение 4 * 7 28

/ Деление 9/2 4

% Остаток при деле-

нии нацело

20 % 6 2

(Обратите внимание, что в приведенной таблице операция деления "/" применялась к

двум целым числам, поэтому результат – тоже целое число.)

Кроме арифметических операций, для проверки условий в операторе if вам могут

потребоваться некоторые логические операции.

Символ Операция Пример Значение

< меньше, чем 3 < 5 TRUE (истина)

<= меньше или равно 43 <= 25 FALSE (ложь)

> больше, чем 4 > 7 FALSE

>= больше или равно 9 >= 2 TRUE

== равно 20 == 6 FALSE

!= не равно 20!= 6 TRUE

&& Логическое И 5 > 2 && 6 > 10 FALSE

|| Логическое ИЛИ 5 > 2 || 6 > 10 TRUE

18

ЛЕКЦИЯ 2. Переменные, типы данных и выражения

Идентификаторы

В исходном тексте программ на Си++ используется довольно много англий-

ских слов и их сокращений. Все слова (идентификаторы), встречающиеся в програм-

мах, можно разделить на три категории:

1) Служебные слова языка. Например, это слова if, int и else. Назначение

этих слов предопределено и его нельзя изменить. Ниже приведен более

полный список служебных слов:

asm continue float new signed try

auto default for operator sizeof typedef

break delete friend private static union

case do goto protected struct unsigned

catch double if public switch virtual

char else inline register template void

class enum int return this volatile

const extern long short throw while

По назначению эти слова можно разбить на отдельные группы (прил. 8.1).

2) Библиотечные идентификаторы. Назначение этих слов зависит от среды

программирования. В случае серьезной необходимости программист может

изменить их смысл. Примеры таких слов: cin, cout и sqrt (имя функции

извлечения квадратного корня).

3) Идентификаторы, введенные программистом. Эти слова "создаются"

программистом – например, имена переменных (такие, как year_now и another_

age в программе 1.5.1).

Идентификатором не может быть произвольная последовательность символов.

По правилам Си++, идентификатор начинается с буквы или символа подчеркивания

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

Типы данных

2.1 Целые числа

Правила Си++ требуют, чтобы в программе у всех переменных был задан тип

данных. Тип данных int встречался нам уже неоднократно. Переменные этого типа

применяются для хранения целых чисел (integer). Описание переменной, как имею-

щей тип int, сообщает компилятору, что он должен связать с идентификатором

(именем) переменной количество памяти, достаточное для хранения целого числа во

время выполнения программы.

Границы диапазона целых чисел, которые можно хранить в переменных типа

int, зависят от конкретного компьютера. В Си++ есть еще два целочисленных типа –

short int и long int. Они представляют, соответственно, более узкий и более

широкий диапазон целых чисел, чем тип int. Добавление к любому из этих типов

префикса unsigned означает, что в переменной будут хранится только неотрица-

тельные числа. Например, описание:

unsigned short int year_now, age_now, another_year, another_age;

19

резервирует память для хранения четырех относительно небольших неотрицательных

чисел.

Приведем несколько полезных правил, касающихся записи целочисленных

значений в исходном тексте программ.

1) Нельзя пользоваться десятичной точкой. Значения 26 и 26.0 одинаковы, но

"26.0" не является значением типа "int".

2) Нельзя пользоваться запятыми в качестве разделителей тысяч. Например,

число 23,897 следует записывать как "23897".

3) Целые значения не должны начинаться с незначащего нуля. Он применяется

для обозначения устаревших восьмеричных чисел, так что компилятор бу-

дет рассматривать значение "011" как число 9 в восьмеричной форме.

2.2 Вещественные числа

Для хранения вещественных чисел применяются типы данных float и

double. Смысл знаков "+" и "-" для вещественных типов совпадает с целыми. По-

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

анты записи "+523.5", "523.5" и "523.500" представляют одно и то же значение. В

Си++ также допускается запись в формате с плавающей запятой (в экспоненциальном

формате) в виде мантиссы и порядка. Например, 523.5 можно записать в виде

"5.235e+02" (т.е. 5.235*10*10), а -0.0034 в виде "-3.4e-03".

В большинстве случаев используется тип double, он обеспечивает более высо-

кую точность, чем float. Максимальную точность и наибольший диапазон чисел

достигается с помощью типа long double, но он требует больше памяти (в

Visual C++ 10 байт на число), чем double (8 байт).

2.3 Преобразование типов в выражениях

При выполнении вычислений иногда бывает нужно гарантировать, что опреде-

ленное значение будет рассматриваться как вещественное число, даже если на самом

деле это целое. Чаще всего это нужно при делении в арифметических выражениях.

Применительно к двум значениям типа int операция деления "/" означает деление

нацело, например, 7/2 равно 3. В данном случае, если необходимо получить результат

3.5, то можно просто добавить десятичную точку в записи одного или обоих чисел:

"7.0/2", "7/2.0" или "7.0/2.0". Но если и в числителе, и в знаменателе стоят перемен-

ные, а не константы, то указанный способ не подходит. Вместо него можно приме-

нить явное преобразование типа. Например, значение "7" преобразуется в значение

типа double с помощью выражения "double(7)". Поэтому в выражении

answer = double(numerator) / denominator

операция "/" всегда будет рассматриваться компилятором как вещественное деление,

даже если "numerator" и "denumerator" являются целыми числами. Для явного преоб-

разования типов можно пользоваться и другими именами типов данных. Например,

"int(14.35)" приведет к получению целого числа 14.

20

2.4 Символьный тип

Для хранения символьных данных в Си++ предназначен тип "char". Перемен-

ная типа "char" рассчитана на хранение только одного символа (например, буквы

или пробела). В памяти компьютера символы хранятся в виде целых чисел. Соответ-

ствие между символами и их кодами определяется таблицей кодировки, которая зави-

сит от компьютера и операционной системы. Почти во всех таблицах кодировки есть

прописные и строчные буквы английского алфавита, цифры 0,...,9, и некоторые

специальные символы, например, #,.,!, +, - и др. Самой распространенной таблицей

кодировки, скорее всего, является таблица символов ASCII.

В тексте программ символьные константы типа "char" надо заключать в оди-

ночные кавычки, иначе компилятор поймет их неправильно и это может привести к

ошибке компиляции, или, что еще хуже, к ошибкам времени выполнения. Например,

"'A'" является символьной константой, но "A" будет рассматриваться компилятором в

качестве имени переменной. Аналогично, "'9'" является символом, а "9" – целочис-

ленной _______константой.

Т.к. в памяти компьютера символы хранятся в виде целых чисел, то тип "char"

на самом деле является подмножеством типа "int". На Си++ разрешается использо-

вать символы в арифметических выражениях. Например, на любом компьютере с

таблицей ASCII следующее выражение даст истинное значение (TRUE, или 1):

'9'-'0' == 57-48 == 9

В таблице ASCII кодом символа '9' является десятичное число 57 (в шестнадца-

теричной записи 0x39), а ASCII–код символа '0' равен десятичному числу 48 (шестна-

дцатеричное значение 0x30). Приведенное выражение можно переписать в виде:

57-48 == 0x39-0x30 == 9

Кодами ASCII удобнее пользоваться в шестнадцатеричной форме. При записи

шестнадцатеричных чисел в Си++ применяется двухсимвольный префикс "0x".

Переменные типа "char" существенно отличаются от "int" при выполнении

ввода данных с клавиатуры и вывода на экран. Рассмотрим следующую программу.

#include <iostream.h>

int main()

{

int number;

char character;

cout << "Напечатайте символ и нажмите Enter:\n";

cin >> character;

number = character;

cout << "Вы ввели символ '" << character;

cout << "'.\n";

cout << "В памяти компьютера он хранится в виде числа ";

cout << number << ".\n";

return 0;

}

Программа 2.1.

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

21

Напечатайте символ и нажмите Enter:

9

Вы ввели символ '9'.

В памяти компьютера он хранится в виде числа 57.

Программу 2.1 можно изменить так, чтобы она печатала всю таблицу символов

ASCII. Для этого придется применить "оператор цикла for". "Цикл for" является

примером оператора цикла – эти операторы будут рассмотрены подробно в одной из

следующих лекций. Оператор for имеет следующий синтаксис:

for (инициализация; условие_повторения; изменение_значений)

{

Оператор 1;

...

...

Оператор N;

}

Цикл for выполняется в следующем порядке: (1) Сначала выполняется опера-

тор инициализации. (2) Выполняется проверка, является ли условие_повторения истин-

ным. Если условие ложно, то оператор for завершается. Если условие истинно, то

последовательно выполняются операторы тела цикла Оператор 1... Оператор N, и затем

выполняется оператор изменение_значений. После этого происходит переход на нача-

ло шага (2).

Чтобы код символа вывести на экран в шестнадцатеричной форме, надо снача-

ла послать на экран служебный символ-манипулятор. Программа для печати фраг-

мента таблицы ASCII (от 32-го символа (пробел) до 126-го (символ '~')), будет выгля-

деть так:

#include <iostream.h>

int main()

{

int number;

char character;

for (number = 32; number <= 126; number = number + 1)

{

character = number;

cout << "Символ '" << character;

cout << "' имеет код ";

cout << dec << number << " (дес.) или ";

cout << hex << number << " (шестнд.).\n";

}

return 0;

}

Программа 2.2.

Программа 2.2 напечатает на экране:

Символ ' ' имеет код 32 (дес.) или 20 (шестнд.).

Символ '!' имеет код 33 (дес.) или 21 (шестнд.).

...

...

Символ '}' имеет код 125 (дес.) или 7D (шестнд.).

Символ '~' имеет код 126 (дес.) или 7E (шестнд.).

22

2.5 Символьные строки

В большинстве рассмотренных примеров программ для вывода на экран часто

используются символьные строки. В Си++ символьные строки заключаются в двой-

ные кавычки. Поэтому в программах часто встречаются операторы вывода вроде:

cout << "' имеет код ";

На самом деле в Си++ строковый тип ("string") не является стандартным ти-

пом данных, таким, как, например, "int", "float" или "char". Строки хранятся в памя-

ти в виде символьных массивов, поэтому строки будут рассматриваться позднее, при

изучении массивов.

2.6 Типы данных, определяемые пользователем

Вопрос о типах данных, определяемых пользователем, будет обсуждаться на-

много более подробно в последующих лекциях. Будет показано, как программист

может определить собственный тип данных, необходимый для решения конкретной

задачи. Средства определения новых типов данных – одна из наиболее мощных воз-

можностей Си++, которые позволяют хранить и обрабатывать в программах на Си++

сложные структуры данных.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: