Intmain()// Основная функция программы – начало выполнения программы

Intmain()

{

cout<< "Это пример программы на языке C++"<<endl;

return 0;

}

Это исходный код программы (исходный код – это текст, написанный на одном из языков высокого уровня – в данном случае – на языке C++). Его нельзя выполнить. Для выполнения программы с помощью компилятора надо получить результирующую программу (объектный код).

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

1. написать текст программы (создать исходный код);

2. откомпилировать этот текст (получить объектный код результирующей программы);

3. выполнить результирующую программу.

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

Программа, приведенная выше, имеет несколько недостатков:

1. При ее выполнении в большинстве случаев (в зависимости от используемой среды программирования) невозможно увидеть результат ее работы;

2. Выведенный в консольное окно текст на русском языке будет нечитабельным.

Вот второй вариант этой же программы, лишенный этих недостатков:

#include<iostream>/* Директива препроцессору включить в текст заголовочный файлбиблиотеки классов C++ для управления вводом – выводом */

usingnamespacestd;/*Директива компилятору использоватьпространство имен std стандартной библиотеки С++ */

Intmain()// Основная функция программы – начало выполнения программы

{

setlocale(0, "");// Установка локальных настроек на вывод русского текста

cout<< "Это пример программы на языке С++"<<endl; // Вывод на экран

system("Pause");// Приостановка выполнения программы

Номера разрядов: 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Значения разрядов: 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 ,

а отрицательное число -22выглядит следующим образом:

Номера разрядов: 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Intmain()

{

inti = 100000, k;

shortj = 10000, m;

k = j; // Короткое целое преобразуется к целому без потерь

m = i; // Преобразованиецелого к короткому целому приводит к искажению данных

cout<<k<< " " <<m<<endl; // На экран будет выведено: 10000 -31072

k = 12500;

m = k; // Потери данных нет

cout<<k<< " " <<m<<endl; // На экран будет выведено: 12500 12500

doubled = 1.8234, n1, n2;

n1 = i; // Без ошибок

n2 = j; // Без ошибок

k = d; // С потерей точности

j = d; // С потерей точности

/* На экран будет выведено: 100000 10000 1 1 */

cout<<n1 << " " <<n2 << " " <<k<< " " <<j<<endl;

d = 1e+100;

k = d; // С потерей данных

m = d; // С потерей данных

/* На экран будет выведено: 1е+100 -2147483648 0 */

cout<< d << " " << k << " " << m <<endl;

system("Pause");

return 0;

}

Операция присваивания в свою очередь является выражением, значением которого является значение переменной в левой части после присваивания (эту переменную часто называют L-значением (от слова left– левая сторона)).Например:

#include<iostream>

usingnamespacestd;

Intmain()

{

inti = 7, j = 30, k;

cout<<i * j<<endl;

cout<< (k = i * j) <<endl;

cout<< k <<endl;

system("Pause");

return 0;

}

Результат работы программы: 210,210, 210.

Благодаря тому, что операция присваивания является выражением, в языке C++ возможно множественное присваивание: <Переменная1> = <Переменная2> = … = <ПеременнаяN> = <Выражение>. Например:

#include <iostream>

using namespace std;

Int main()

{

inti = 7, j = 30, k, l, m, n;

k = l = m = n = i + j;

cout<< k << " " << l << " " << m << " " << n << " " <<endl;

system("Pause");

return 0;

}

Результат работы программы: 37 37 37 37

Операция присваивания имеет самый низкий приоритет

Операции составного присваивания

Операции этой группы перечислены в следующей таблице:

Операция Использование Эквивалент
*= a *= b a = a * b
/= a /= b a = a / b
%= a %= b a = a % b
+= a += b a = a + b
-= a -= b a = a - b
<<= a <<= b a = a << b
>>= a >>= b a = a >> b
&= a &= b a = a & b
|= a |= b a = a | b
^= a ^= b a = a ^ b

Общий формат записи выражений с использованием этих операций: < Переменная>< Операция >= < Выражение>

Эквивалентом этого формата в общем случае является:< Переменная> = <Переменная>< Операция >< Выражение>

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

17. Понятие L – значения.

Операция присваивания в свою очередь является выражением, значением которого является значение переменной в левой части после присваивания (эту переменную часто называют L-значением (от слова left– левая сторона)).Например:

#include<iostream>

usingnamespacestd;

Intmain()

{

inti = 7, j = 30, k;

cout<<i * j<<endl;

cout<< (k = i * j) <<endl;

cout<< k <<endl;

system("Pause");

return 0;

}

Результат работы программы: 210,210, 210.

18. Преобразование типов данных.

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

Определены переменные

inta = 5;

doubleb = 7.6;

В программе необходимо подсчитать их сумму a + b.

Внутреннее (машинное) представление типа intи типа double существенно различаются. Существенно различаются и процедуры сложения целых значений и процедуры сложения вещественных значений. Как же тогда сложить целое и вещественное? Выход – преобразовать оба значения к одному и тому же типу данных, а затем выполнить соответствующую операцию. Но если преобразовать значение переменной b к целому типу данных (отбросить дробную часть или округлить до ближайшего целого) результат будет равен либо 12, либо 13, то есть произошла потеря точности. А вот если сначала преобразовать значение a к типу double и сложить их как вещественные значения, тогда точность потеряна не будет (результат будет равен 12.6 и будет вещественного типа). На самом деле так и происходит.

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

В языке C++ различают неявное (автоматическое) и явное преобразование типов данных.

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

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

1. Все данные типов char и shortint преобразуются к типу int.

2. Если хотя бы один из операндов имеет тип double, то и другой операнд преобразуется к типу double (если он другого типа); результат вычисления имеет тип double.

3. Если хотя бы один из операндов имеет тип float, то и другой операнд преобразуется к типу float (если он другого типа); результат вычисления имеет тип float.

4. Если хотя бы один операнд имеет тип long, то и другой операнд преобразуется к типу long (если он другого типа); результат имеет тип long.

5. Если хотя бы один из операндов имеет тип unsigned, то и другой операнд преобразуется к типу unsigned (если его тип не unsigned); результат имеет тип unsigned.

Если ни один из случаев 1-5 не имеет места, то оба операнда должны иметь тип int; такой же тип будет и у результата.

Следует отметить, что компиляторы языка C++ достаточно свободно выполняют подобные преобразования, что может в ряде случаев привести к неожиданным результатам. Например:

#include <iostream>

using namespace std;

Int main()

{

unsigned a = 5;

int b = 10;

cout<< a << " - " << b << " = " << a - b <<endl;

system("Pause");

return 0;

}

Результат работы программы: 5 – 10 = 4294967291

Таким образом, несмотря на то, что язык C++ достаточно «снисходителен» к действиям программиста, это требует от программиста еще большей дисциплины в его действиях и четких знаний нюансов языка программирования.

Для исправления ошибки в работе предыдущей программы можно, например, изменить вычисление выражения a–bследующим образом: (int) a – bили int(a) – b.В этом случае мы получим правильный результат: 5 – 10 = -5.

Здесь было использовано явное преобразование типов данных.

Явное преобразование типов данных осуществляется с помощью соответствующей операции преобразования типов данных, которая имеет один из двух следующих форматов:(<тип данных>) <выражение>или <тип данных> (<выражение>). Например:

(int) 3.14int (3.14)

(double) aилиdouble (a)

(long) (a + 1e5f) long (a + 1e5f)

Подобные преобразования имеют своим исходом три ситуации:

· преобразование без потерь;

· с потерей точности;

· с потерей данных.

Преобразование происходит без потерь, если преобразуемое значение принадлежит множеству значений типа, к которому осуществляется преобразование. Например:

shorta = 100;

cout<< (int) a<<endl; // На экран выведено 100

cout<< (char) a<<endl; // Выведена буква d(ее десятичный эквивалент - 100)

cout<< (float) a<<endl; // На экран выведено 100

cout<< (double) a<<endl; // На экран выведено 100

float b = 3.14f;

cout<< (double) b <<endl; // Наэкранвыведено3.14

double d = 3.14;

cout<< (float) d<<endl; // На экран выведено 3.14

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

doubled = 3.74;

cout<< (int) d<<endl; // Наэкранвыведено3

А вот попытки преобразования значений выходящих за пределы диапазона типа данных, к которому осуществляется преобразование, приводят к полному искажению данных. Например:

int a = -100;

cout<< (unsigned) a <<endl; // Наэкранвыведено4294967196

int a = 50000;

cout<< (short) a <<endl; // Наэкранвыведено-15536

float b = 3e+9f;

cout<< (int) b <<endl; // Наэкранвыведено-2147483648

double d = 3e+9;

cout<< (int) d <<endl; // Наэкранвыведено-2147483648

double d = 3e+40;

cout<< (float) d <<endl; // Наэкранвыведено1.#INF- переполнение

double d = -3e+40;

cout<< (float) d<<endl; // На экран выведено -1.#INF- переполнение

Рассмотренная операция преобразования типов перешла в C++ изC. В C++ имеются свои операции преобразования типов данных. Например, рассмотренные выше преобразования в C++ можно было бы выполнить с помощью операции static_cast, имеющей следующий формат:static_cast<тип данных> (выражение).Например:static_cast<double> (a + 2e+40f)

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

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

19. Арифметические преобразования.

Унарный плюс (+) и унарный минус (-)Единственный операнд любого арифметического типа. Формат записи: + < Выражение >,- < Выражение >

Унарный плюс возвращает значение операнда без изменений.

Унарный минус (его иногда называют арифметическим отрицанием) меняет знак операнда на обратный.

Умножение - * - бинарная операция. Примеры записи: a * b 2 * 3 a * 0.56

Операнды могут быть любого арифметического типа данных. Тип данных результата операции определяется правилами неявного преобразования типов.

При выполнении возможен выход реального значения результата за допустимый диапазон значений типа данных – при этом значение результата операции трудно предсказать. Например: cout<< 1000000 * 1000000; // Результат: -727379968,cout<< 1е20f * 1e20f; // Результат: 1.#INF –переполнение (+ бесконечность), cout<< 1е20f * -1e20f; // Результат: -1.#INF –переполнение (- бесконечность).

Деление - / - бинарная операция. Примеры записи: a / b 2 / 3 a / 0.56

Если оба операнда являются целыми, то результат деления будет целым. В этом случае целый результат получается отбрасыванием дробной части от полученного реального значения (не округление). Например:5 / 3 - результат равен 1.

Если все же в результате выполнения этой операции требуется получить значение с дробной частью, необходимо чтобы хотя бы один из операндов был вещественного типа. Например:5.0 / 3или 5 / 3.или5.0 / 3.0 или5 / 3fили 5f / 3или 5f / 3fили float (5) / 3илиdouble (5) / 3

Результатом вычисления всех этих выражений будет значение 1.6666… одного из вещественных типов.

Однако, например, выражение double (5 / 3)хотя и будет вещественного типа, но его значение все равно будет равно 1, поскольку сначала будет вычислено выражение в скобках, результат которого будет целого типа и будет равен 1, а затем это значение будет приведено к вещественному типу.

При выполнении операции возможен выход реального значения результата за допустимый диапазон значений типа данных – при этом значение результата операции трудно предсказать. Например: cout<< 1е35f / 0.0001f; // Результат: 1.#INF –переполнение (+ бесконечность), cout<< 1е20f / -0.0001f; // Результат: -1.#INF –переполнение (- бесконечность), cout<< 1е200 / 1e-200; // Результат: 1.#INF –переполнение (бесконечность).

Если первый операнд вещественного типа, то деление на 0 дает значение 1.#INF или -1.#INF. Если же он целого типа, возникает ошибка режима исполнения (деление на 0).

Остаток от деления - % - бинарная операция. Операнды только целого типа. Результат операции целого типа. Например: 5 % 1 - результат 0,5 % 2 - результат 1,5 % 3 - результат 2,5 % 4 - результат 1, 5 % 5 - результат 0, 5 % 6 - результат 5…..

Если второй операнд равен 0, возникает ошибка режима исполнения (деление на 0).

Сложение (+) и вычитание (-) – бинарные операции. Операнды могут быть любых арифметических типов данных. Примеры записи:a + b, a – b

Тип результата операций определяется правилами неявного преобразования типов.

При выполнении операций возможны ошибки переполнения и некорректного преобразования типов данных операндов.Например:

unsignedshortn = 0, m;

m = n - 1;

cout<<m<<endl; //На экран будет выведено65535

n = m + 1;

cout<<n<<endl; //На экран будет выведено0

20. Операции инкремента и декремента, их разновидности

Инкремент (++) и декремент (--) – унарные операции увеличения и уменьшения операнда на 1соответственно. Операнд может быть любого арифметического типа данных.

Операции имеют две формы – префиксную(++a, --a) ипостфиксную(a++, a--).

Независимо от формы операция инкремента эквивалентна следующему оператору: a = a + 1; аоперациядекрементаследующему:a = a - 1; Например:

#include <iostream>

using namespace std;

Int main()

{

inti = 7, j = 10;

++ i;

j ++;

cout<<i<< "\t" <<j<<endl; // На экран выведено 8 11

-- i;

j --;

cout<<i<< "\t" <<j<<endl; // На экран выведено 7 10

system("Pause");

return 0;

}

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

Немного изменим текст программы:

#include <iostream>

using namespace std;

Int main()

{

inti = 7, j = 10;

cout<< ++ i<< "\t " <<j ++ <<endl; // На экран выведено 8 10

cout<<i<< "\t " <<j<<endl; // На экран выведено 8 11

cout<< -- i<< "\t " <<j -- <<endl; // На экран выведено 7 11

cout<<i<< "\t " <<j<<endl; // На экран выведено 7 10

system("Pause");

return 0;

}

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

В первом примере операторы ++ i; j ++;просто изменяютзначения переменных iи jбез какой-либо другой обработки и только после окончания работы этих операторов на экран выводятся эти измененные значения. Поэтому различие между префиксной и постфиксной формами не чувствуется. То же самое происходит и при выполнении операторов -- i; j--;.

Во втором примерепрефиксные и постфиксные формыопераций инкремента и декремента участвуют в выполнении оператора вывода данных на экран. Поэтому при выполнении префиксных операций сначала происходит изменение значений переменной i, потом эти измененные значения выводятся на экран, а при выполнении постфиксных операций сначала выводятся неизмененные значения переменной j, а уже после этого производятся изменения значения этой переменной.

А как интерпретировать такие выражения:a+++b, a---b

Эти выражения следует интерпретировать так:(a++) + b,(a--) - b

Но не так: a + (++b), a - (--b)

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

21. Операции отношения.

Операции этой группы служат для сравнения значений. Сюда входят следующие операции:

· == - равно;

· != - не равно;

· >- больше;

· >= - больше или равно;

· < - меньше;

· <= - меньше или равно.

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

Примеры: a == b,a != b,a> 10,(a - 3) >= (b + 10).

22. Логические операции.

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

· !- логическое отрицание (логическое НЕ);

· && - конъюнкция (логическое И);

· || - дизъюнкция (логическое ИЛИ).

Первая операция унарная, две остальные – бинарные. Операнды – выражения любого арифметического типа данных, значения которых интерпретируются как значения логического типа (отличное от 0 значение – true; 0 - false) . Результат этих операций - логического типа.

Правила записи и результаты выполнения логических операций приведены в следующей таблице:

a b !a a&&b a||b

Пусть, например, имеется математическое неравенство:0 <x< 10. На языке C++ это неравенство следует записывать так:(0 <x) && (10 >x)или (х > 0) && (x< 10). А математическое неравенство 0 >x> 10должно выглядеть следующим образом: (0 >x) || (10 <x)или (х < 0) || (x> 10).

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

Например. Если в выражении (a + 10) && (b – 1)значение первого (левого) операнда a + 10равно 0 (false) (это будет при значении a = -10), то вычисление второго (правого) операнда b – 1не выполняется, так как и без его вычисления, значение результата операции &&уже известно – это false. А в выражении (a + 10) || (b – 1) второй операнд не будет вычисляться в том случае, если первый операнд не равен 0– в этом случае результат операции ||и так уже известен – он равен true.

23. Побитовые операции сдвига

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

Операции сдвига - <<и >> - бинарные операции. Операнды целого типа. Результат также целого типа. Формат записи:< Операнд 1 ><<< Операнд 2 > -сдвиг влево, < Операнд 1 >>>< Операнд 2 > -сдвиг вправо

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

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

unsigned a = 20, n = 3, r;

r = a << n;

cout<< r <<endl; //Наэкранвыведено160

r = a >> n;

cout<<r<<endl; //На экран выведено 2

Иллюстрация:

Номер разряда: 31 30 … 8 7 6 5 4 3 2 1 0

Значение a: 0 0 … 0 0 0 0 1 0 1 0 0 = 20

Операция: a<<n

Значение r: 0 0 … 0 1 0 1 0 0 0 0 0 = 160

Операция: a>>n

Значение r: 0 0 … 0 0 0 0 0 0 0 1 0 = 2

Операция сдвига влево осуществляет перемещение битов левого операнда a в сторону больших разрядов на количество разрядов, равное значению правого операнда n. Это эквивалентно умножению значения a на 2 в степени n(20 * 8 = 160).

Операция сдвига вправо осуществляет перемещение битов левого операнда a в сторону меньших разрядов на количество разрядов, равное значению правого операнда n. Это эквивалентно делению значения a на 2 в степени n(целочисленное деление 20 / 8 = 2).

Используя операцию сдвига влево очень просто получить любую целую степень двойки в диапазоне степеней равной количеству двоичных разрядов правого операнда без 1. Например, так:1U<< 20 - равно 2 в степени 20, то есть 1048576

При сдвиге влево (в сторону старших разрядов), освобождающиеся младшие разряды замещаются 0 (нулями). При сдвиге вправо возможны две ситуации: если первый операнд беззнаковый (unsigned), то освобождающиеся старшие разряды замещаются 0; если же первый операнд знаковый, то освобождающиеся старшие разряды замещаются либо знаковым разрядом, либо 0 (нет гарантии - зависит от реализации).

Примеры применения побитовых операций.

Примеры:

unsigned a = 20, n = 3, r;

r = a << n;

cout<<r<<endl; //На экран выведено 160

r = a >> n;

cout<<r<<endl; //На экран выведено 2

Иллюстрация:

Номер разряда: 31 30 … 8 7 6 5 4 3 2 1 0

Значение a: 0 0 … 0 0 0 0 1 0 1 0 0 = 20

Операция: a<<n

Значение r: 0 0 … 0 1 0 1 0 0 0 0 0 = 160

Операция: a>>n

Значение r: 0 0 … 0 0 0 0 0 0 0 1 0 = 2

inta = 14, b = 7, r;

r = a&b;

cout<<r<<endl; //На экран выведено6

r = a | b;

cout<<r<<endl; //На экран выведено15

r = a ^ b;

cout<<r<<endl; //На экран выведено9

Иллюстрация:

Номер разряда: 31 30 … 8 7 6 5 4 3 2 1 0

Значение a: 0 0 … 0 0 0 0 0 1 1 1 0 = 14

Значение b: 0 0 … 0 0 0 0 0 0 1 1 1 = 7

Операция: a&b

Значение r: 0 0 … 0 0 0 0 0 0 1 1 0 = 6

Операция: a | b

Значение r: 0 0 … 0 0 0 0 0 1 1 1 1 = 15

Операция: a ^ b

Значение r: 0 0 … 0 0 0 0 0 1 0 0 1 = 9

unsigneda = 1234; // Целое значение, битами которого мы будем управлять

unsignedshortn = 4;// Номер необходимого бита (от 0 до 31)

boolr; // Значение результата (0 или 1)

/* Узнаем, чему равен n-й бит (двоичный разряд) значения a. Результат поместим в переменную r */

r = a& (1U<<n);

cout<< "Разряд с номером " <<n<< " равен " <<r<<endl; //значение1

Иллюстрация вычисления этого выражения:

Номер разряда: 31 30 … 11 10 9 8 7 6 5 4 3 2 1 0

Intmain()// Основная функция программы – начало выполнения программы - student2.ru 1U: 0 0 … 0 0 0 0 0 0 0 0 0 0 0 1 = 1

1U<<n: 0 0 … 0 0 0 0 0 0 0 1 0 0 0 0

Значение a: 0 0 … 0 1 0 0 1 1 0 1 0 0 1 0 = 1234

a& (1U<<n): 0 0 … 0 0 0 0 0 0 0 1 0 0 0 0 = 16

Int main ()

{

setlocale (0, "");

int a;

printf ("Введите целое число:\t");

scanf ("%d", &a);

printf ("Выввелизначение:\t%d\n\n", a);

system ("Pause");

return 0;

}

Второй способ, характерный для C++, основан на использовании стандартных потоков ввода (cin) и вывода (cout). Та же самая программа в стиле C++ будет выглядеть так:

#include <iostream>

using namespace std;

Int main ()

{

setlocale (0, "");

int a;

cout<< "Введите целое число:\t";

cin>>a;

cout<< "Вы ввели значение:\t" <<a<< "\n\n";

// cout<< "Вы ввели значение:\t" <<a<<endl<<endl;

system ("Pause");

return 0;

}

В одной и той же программе совмещать эти два способа не рекомендуется.

При использовании потоков для вывода данных на экран используется операция <<, которая так и называется: операция вывода или операция вставки (данные "вставляются" в поток вывода).

Ввод данных с клавиатуры осуществляется с помощью операции ввода>>(операция извлечения данных из потока ввода).

Обе эти операции "знают" как осуществлять ввод и вывод стандартных простых типов данных. Более того эти операции можно "научить", как осуществлять ввод/вывод нестандартных пользовательских типов данных (перегрузка операций).

Вывод текстовых строк

Текстовые (строковые) литералы в C++ представляются как последовательность символов, заключенная в двойные кавычки. Например: "Это пример текстовой строки".

Вывод текстовых строк на экран осуществляется через стандартный поток вывода с помощью операции вывода <<: cout<< "Это пример текстовой строки";

Внутрь текстовых строк можно вставлять управляющие escape-последовательности. Escape-последовательности служат для управления выводом, и представляют собой специальные последовательности из двух или более символов, начинающиеся символом обратной наклонной черты - \. При этом каждая такая последовательность воспринимается компилятором как 1 символ. Примерами таких управляющих последовательностей в предыдущих программах являются \t - символ табуляции и \n - символ перевода строки (все эти последовательности приведены в разделе 3.5). С помощью Escape-последовательностей в текстовую строку можно включить любой символ с помощью его восьмеричного или шестнадцатеричного кода (в том числе и символы, которых нет на клавиатуре). Например:cout<< "Это символ с восьмеричным кодом 254:\t\254\n";cout<< "А это символ с шестнадцатеричным кодом xAA:\t\xAA\n";

На экран будут выведены две строки: Это символ с восьмеричным кодом 254: А это символ с шестнадцатеричным кодом xAA: Є

Если на экран необходимо вывести пустую строку, достаточно вставить в поток дважды подряд управляющую последовательность \n:

cout<< "Это первая строка\n";

cout<< "\n";// Вторая строка пустая

cout<< "Это третья строка\n";

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

cout<< "Это " \

"условный " \

"пример " \

"длинного " \

"текста\n"

или так

cout<< "Это " "условный " "пример "

"длинного " "текста\n";

На экран будет выведена одна строка, после чего экранный курсор перейдет на новую строку (управляющая последовательность \n): Это условный пример длинного текста

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

Ввод текстовых строк с клавиатуры будет рассмотрен позже.

Int main ()

{

setlocale (0, "");

inti;

double d;

char c;

bool b;

cin>>i;

cout<<i;

cin>> d;

cout<< d;

cin>> c;

cout<< c;

cin>> b;

cout<< b;

system ("Pause");

return 0;

}

Особенности:

1. Ввод/вывод целочисленных значений осуществляется обычным образом в десятичной системе счисления.

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

3. Формат вывода вещественных значений выбирается автоматически в зависимости от выводимого значения.

4. Ввод символьных значений можно осуществлять только в виде одиночного символа. При вводе нескольких символов переменной cбудет присвоен только первый символ. Могут возникнуть сложности с вводом русских букв.

5. Ввод/вывод логических значений осуществляется в числовом формате (0 - false, 1 - true).

Замечание:

При вводе числовых данных с клавиатуры могут возникать непредвиденные ошибки, вызванные вводом символов, недопустимых для числовых форматов. Например:inti;cin>>i;

При попытке ввода с клавиатуры числа 1234 допущена ошибка - набрано 12y34 и нажата клавиша ENTER (ошибочно была нажата клавиша y). Переменная i в этом случае будет содержать значение 12, и эта ошибка может привести к непредсказуемому дальнейшему поведению программы. В любом случае символы из потока ввода извлекаются оператором >>до тех пор, пока они соответствуют числовому формату. Как только в потоке ввода встречается символ, не соответствующий числовому формату, уже извлеченные символы преобразуются в числовое значение и присваиваются переменной ввода. Остальные символы игнорируются.

31. Флаги форматирования потоков ввода\вывода.

Более гибкое управление вводом/выводом (форматирование ввода/вывода) в C++ осуществляется либо с помощью установки флагов форматирования, либо с помощью специальных манипуляторов ввода/вывода.

Intmain ()

{

setlocale (0, "");

cout<< 255 <<endl; //На экране видим 255 -по умолчанию установлен флаг dec

cout.setf (ios :: hex); //Включаем флагhex- хотим видеть на экране ff

cout<< 255 <<endl; //На экране видим 255- изменений не произошло

system ("Pause");

return 0;

}

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

cout.unsetf(ios :: dec); //Отключаемфлагdec

cout.setf(ios :: hex); //Включаемфлагhex- хотим видеть на экране ff

cout<< 255 <<endl;//На экране видим ff- то, что хотели

Среди всех флагов можно выделить три группы, в каждой из которых флаги управляют одной и той же характеристикой ввода / вывода, но являются взаимоисключающими. Флагам каждой из этих групп в классе ios присвоены обобщающие имена:

Группа Флаги Обобщающее имя
Флаги основания систем счисления dec, oct,hex basefield
Флаги выравнивания left, right,internal adjustfield
Флаги формата вещественных значений scientific,fixed floatfield

Обобщающие имена групп удобно использовать для выполнения операции со всеми флагами группы, например, для сброса всех флагов группы:cout.unsetf (ios ::basefield); //Отключаемфлагиdec, oct, hexза один прем

Болеетого, функциюsetfможно использовать с двумя параметрами: setf (новые флаги, маска)

В этом случае функция setfустанавливает только те флаги, которые одновременно присутствуют и в первом и во втором параметре, а те флаги, которые присутствуют во втором параметре, но отсутствуют в первом, будут сброшены. Это дает возможность отключать и включать флаги за один вызов функции setf. Например, для установки любого флага из группы basefield достаточно использовать всего один оператор: cout.setf (ios :: hex, ios ::basefield);

Здесь второй параметр содержит три флага: dec, oct,hex. Первый параметр содержит флаг hex. Этот флаг будет установлен, а флаги dec и oct будут сброшены.

В классе coutимеются еще несколько функций управляющих форматом вывода данных. К ним относятся:

· precision - определяет точность представления вещественных значений;

· width - устанавливает ширину поля вывода;

· fill - определяет символ заполнения при выводе данных.

34. Управление шириной поля вывода и выравниванием данных при выводе

35. Управление форматом вывода вещественных значений

36. Основные понятия структурного программир<

Наши рекомендации