Этапы и проблемы решения задач с использованием компьютера 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Этапы и проблемы решения задач с использованием компьютера



Введение

 

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

 

Алфавит языка

Алфавит C++ включает:

· прописные и строчные латинские буквы и знак подчеркивания;

· арабские цифры от 0 до 9;

· специальные знаки:

“ { }, | [ ] () + - / % *. \ ‘:? < = >! & # _; ^

· пробельные символы: пробел, символы табуляции, символы перехода на новую строку.

Из символов алфавита формируются лексемы (лексема или элементарная конструкция - минимальная единица языка, имеющая самостоятельный смысл):

· ключевые (зарезервированные) слова;

· идентификаторы;

· знаки операций;

· константы;

· разделители (скобки, точка, запятая, пробельные символы);

· комментарии.

Границы лексем определяются другими лексемами, такими, как разделители или знаки операций.

Ключевые слова

Всего в C++ 63 ключевых слов:

 

asm else new this
auto enum operator throw
bool explicit private true
break export protected try
case extern public typedef
catch false register typeid
char float reinterpret_cast typename
class for return union
const friend short unsigned
const_cast goto signed using
continue if sizeof virtual
default inline static void
delete int static_cast volatile
do long struct wchar_t
double mutable switch while
dynamic_cast namespace template  

 

Ключевые слова предопределены в языке программирования и имеют вполне определенный смысл для компилятора. Использовать эти слова по какому-либо другому назначению нельзя.

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

Идентификаторы – это имена различных программных объектов (имена переменных, констант, функций и т.д.).

Синтаксически правильный идентификатор – это последовательность латинских букв, цифр и символов «_» - нижнее подчеркивание, начинающаяся с буквы или символа «_».

Важно помнить, что в C++ различается строчное и прописное написание букв. То есть, например, идентификаторы ABC, Abc и abc представляют в программе не один и тот же объект, а три разных объекта. Некоторые компиляторы позволяют отключить такую чувствительность к написанию букв, но делать этого не следует, так как это может помешать переносимости программ с одного компилятора на другой.

Максимальная длина идентификатора в стандарте языка не установлена, однако, в некоторых компиляторах это значение ограничено 32 символами или может регулироваться с помощью настроек компилятора.

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

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

Имена программных объектов (идентификаторов) должны отражать назначение именуемых объектов. Простые (обезличенные) идентификаторы следует использовать для различных вспомогательных объектов, когда их область действия ограничена.

Знаки операций

Служат для указания действий над операндами. В зависимости от количества операндов в C++ имеются унарные, бинарные и одна тернарная операции. Знаки операций могут изображаться одним или несколькими символами. Если операция содержит в своем изображении несколько символов, то между символами не должно быть пробелов. Некоторые операции в C++ в зависимости от контекста могут выполнять разные действия. Большинство стандартных операций можно переопределять (перегружать).

Константы

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

Комментарии

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

В C++ имеются комментарии двух видов: однострочные и многострочные.

Однострочный комментарий начинается двумя символами // (прямой косой черты) и заканчивается в конце строки текста программы.

Многострочный комментарий – начинается символами /* и заканчивается */ и может содержать множество строк. Многострочные комментарии не могут вкладываться друг в друга. Однострочные комментарии могут находиться внутри многострочных комментариев.

Int main()

{

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

return 0;

}

 

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

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

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

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

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

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

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

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

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

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

 

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

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

Int main()

{

setlocale(0, "");

cout << "5 + 7 = " << sum(5, 7) << endl;

system("Pause");

return 0;

}

 

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

 

#include <iostream>

using namespace std;

int sum(int a, int b)

{

int c = a + b;

return c;

}

Int main()

{

int s1, s2;

setlocale(0, "");

cout << "Введите первое слагаемое: ";

cin >> s1;

cout << "Введите второе слагаемое: ";

cin >> s2;

cout << s1 << " + " << s2 << " = " << sum(s1, s2) << endl;

system("Pause");

return 0;

}

 

Понятие типов данных

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

Память компьютера можно представить в виде непрерывной последовательности двоичных ячеек, каждая из которых может находиться в двух состояниях условно обозначаемых 0 и 1. Каждая такая двоичная ячейка называется битом. Вся эта последовательность ячеек условно разбита на порции из 8 бит, называемые байтами. Таким образом, 1 байт = 8 битам. Байт является основной единицей измерения объема памяти.


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

Пусть, например, программе необходимо вывести на экран данные, хранящиеся в байте с адресом 1. Но как это сделать? Ведь двоичный код, содержащийся в этом байте, можно трактовать по-разному: это может быть число, а может быть это некоторая буква. Таким образом, программе для правильной обработки этого байта необходимо «знать» что это – число или буква. Другими словами, программе необходимо точно представлять какие данные хранятся в этом байте памяти.

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

Тип данных для каждого программного объекта, представляющего данные, определяет:

· характер данных (число, со знаком или без знака, целое или с дробной частью, одиночный символ или текст, представляющий последовательность символов и т.д.);

· объем памяти, который занимают в памяти эти данные;

· диапазон или множество возможных значений;

· правила обработки этих данных (например, допустимые операции).

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

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

Переменные, константы

В программах данные представлены константами и переменными.

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

Общее правил определения переменной можно сформулировать так:

 

[класс памяти] <тип данных> <идентификатор - имя> [инициализатор];

Понятие класс памяти определяет такие важные характеристики как время жизни и область видимости переменных. Эти понятия будет рассмотрено позднее, и в следующих примерах они пока не используется.

Примеры описания переменных:

 

int а; // переменная a типа int (целого типа)

double х; // переменная х типа double (вещественного типа с двойной точностью)

unsigned short int d; // переменная d – короткое целое без знака

 

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

 

int i, j, k;

 

Описание переменной можно совместить с ее инициализацией:

 

int а = 1213; // переменная a инициализирована значением 1213

double х = 0.003; // переменная х инициализирована значением 0.003

unsigned short int d = 13; // переменная d инициализирована значением 13

 

Существует альтернативный способ инициализации переменных. Следующие примеры эквивалентны предыдущим:

 

int а (1213); // переменная a инициализирована значением 1213

double х (0.003); // переменная х инициализирована значением 0.003

unsigned short int d (13); // переменная d инициализирована значением 13

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

int i = 0, j, k (10);

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

 

double y = a * x; /* переменная y инициализирована значением равным произведению значений переменных a и x */

 

При инициализации переменной присваивается конкретное значение. Однако, если переменная не инициализирована, это не означает, что она не имеет значения. На самом деле она хранит некоторое значение, которое находилось в этой области памяти до определения переменной. Это значение невозможно предсказать. Такие случайные данные обычно называют “мусором”.

Во время выполнения программы значение переменной можно изменять.

 

Константа – это величина, значение которой в процессе работы программы не изменяется.

Константы бывают двух видов: константы – литералы и именованные константы.

Константы – литералы представляют собой сами значения. Например:

 

123 -245 0.003 -12.45 ’R’ ”Это текст”

Тип данных, которому принадлежит констант – литера, определяется компилятором автоматически по виду самого значения. Способы записи констант – литералов разных типов будет рассмотрены позже при изучении соответствующих типов данных.

Именованные константы задаются с помощью ключевого слова const:

 

const double Pi = 3.14;

const int c1 = 1000, c2 = 2000;

const char point = ’.’;

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

 

Целочисленные типы данных

Размер типа int не определяется стандартом, а зависит от компьютера и компилятора. Для 16-разрядного процессора под величины этого типа отводится 2 байта – в этом случае диапазон возможных значений составляет -32 768... 32 767 (2 в степени 16 различных значений). Для 32-разрядного - 4 байта – диапазон значений -2 147 483 648... 2 147 483 647 (2 в степени 32 различных значений).

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

Спецификатор long означает, что целая величина будет занимать 4 байта. Таким образом, на 16-разрядном компьютере эквиваленты int и short int, а на 32-разрядном — int и long int.

При определении переменных вместо short int или long int можно использовать более короткие обозначения: short или long соответственно:

 

short a;

long b;

Использование типов int, short int (short), long int (long) подразумевает представление целых чисел со знаком, поэтому спецификатор signed можно не указывать.

Внутреннее представление величины целого типа — целое число в двоичном коде. Например, число +22 типа short int (short) представляются в памяти так:

 

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

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

011 07345 -0456

 

В шестнадцатеричном формате значащим разрядам числа должны предшествовать символы 0x или 0X:

 

X12B5 -0xAF2B 0X1FF02

Как уже говорилось ранее, константам, встречающимся в программе, приписывается тот или иной тип в соответствии с их видом. Если этот тип по каким-либо причинам не устраивает программиста, он может явно указать требуемый тип с помощью суффиксов L, l (long) и u, U (unsigned). Например, константа 32L будет иметь тип long и занимать 4 байта. Можно использовать суффиксы L и U одновременно, например, Ox22UL или 05LU.

Вещественные типы данных

Стандарт C++ определяет три типа данных для хранения вещественных значений: float, double и long double. Все эти типы предназначены для представления отрицательных и положительных значений (спецификатор unsigned к ним не применим) в разных диапазонах:

  • тип float занимает в памяти 4 байта с диапазоном абсолютных значений от 3.4е-38 до 3.4е+38;
  • тип double занимает в памяти 8 байт с диапазоном абсолютных значений от 1.7е-308 до 1.7е+308;
  • тип long double занимает в памяти 10 байт с диапазоном абсолютных значений от 3.4e-4932 до 3.4e+4932.

.

Замечание. В консольных приложениях Windows тип данных long double занимает в памяти 8 байт, то есть ничем не отличается от типа double.

 

Константы вещественных типов задаются двумя способами:

· нормальный формат: 123.456 или -3.14;

· экспоненциальный формат: 1.23456e2 (1.23456е+2). Привести другие примеры.

Дробная часть отделяется от целой части точкой, а не запятой.

По умолчанию вещественные константы трактуются как константы типа double. Для явного указания другого типа вещественной константы можно использовать суффиксы F (f) - тип float или L (l) - тип long double:

3.14F - константа типа float,

3.14L - константа типа long double.

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

 

- 1.2345 e +2

| |

мантисса порядок

 

Тип float занимает 4 байта, из которых один двоичный разряд отводится под знак мантиссы, 8 разрядов под порядок и 23 под мантиссу.

Для величин типа double, занимающих 8 байт, под порядок и мантиссу отводится 11 и 52 разряда соответственно. Длина мантиссы определяет точность числа, а длина порядка — его диапазон.

Все вычисления с вещественными значениями осуществляются приближенно, при этом, ошибки вычислений могут достигать весьма существенных значений. Это объясняется дискретностью внутреннего (машинного) представления непрерывного диапазона вещественных значений. Точность представления значений вещественных типов зависит от размера мантиссы. Относительная точность представления вещественных значений остается постоянной при различных значениях порядка. Однако, абсолютная точность существенно зависит от значения порядка (с уменьшением порядка абсолютная точность возрастает).

Дать приближенную оценку точности на примерах.

Пример неточности вычислений:

 

float a = 1e30f, b;

b = a + 1e10f;

cout << b - a << endl; // На экран выведено 0

 

 

Логический тип данных

Величины логического типа могут принимать только значения true и false, являющиеся зарезервированными словами. Внутренняя форма представления значения false - О (нуль). Любое другое значение интерпретируется как true. При преобразовании к целому типу true имеет значение 1 (единица).

В памяти переменные этого типа занимают 1 байт.

Определения переменных этого типа выглядят, например, так:

 

bool b1, b2 = true, b3 (false), b4 = 1, b5 = 0;

 

Константы – литералы задаются ключевыми словами true и false.

Именованные константы этого типа особого смысла не имеют, но имеют право на существование.

Символьный тип данных

Для обозначения этого типа используется ключевое слово char.

Под величину символьного типа отводится количество байт, достаточное для размещения любого символа из набора символов для данного компьютера, что и обусловило название типа. Как правило, это 1 байт. Тип char, как и другие целые типы, может быть со знаком или без знака. В величинах со знаком можно хранить значения в диапазоне от -128 до 127. По умолчанию тип char являемся знаковым, то есть спецификатор signed использовать не обязательно. При использовании спецификатора unsigned значения могут находиться в пределах от 0 до 255. Этого достаточно для хранения любого символа из 256-символьного набора ASCII. Величины типа char могут применяться и для хранения целых чисел, не выходящих за границы указанных диапазонов.

Спецификаторы short и long к этому типу данных не применяются.

Константы - литералы символьного типа представляют собой символы, заключенные в апострофы. Например:

 

’A’ ’!’ ’#’ ’f’ ’ш’ ’я’

В языке C++ существует понятие управляющих или ESCAPE – последовательностей.

Управляющие последовательности начинаются символом обратной косой черты и служат:

· Для представления символов, не имеющих графического изображения. Например: ‘\n’ – перевод экранного курсора в начало следующей строки; ‘\t’ символ табуляции и т.д.

· Для представления некоторых специальных символов, а именно: знака косой черты, апострофа, знака вопроса и кавычки – ‘\\’, ‘\’’, ‘\?’, ‘\”’.

· Для представления любого из 256 символов таблицы ASCII с помощью его восьмеричного или шестнадцатеричного номера. Например: ‘\054’, ‘\x4A’.

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

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

Если в последовательности цифр встречается недопустимая, она считается концом цифрового кода.

Допустимые варианты управляющих последовательностей приведены в следующей таблице:

 

Изображение Шестнадцатеричный код Назначение
  Звуковой сигнал
\b   Возврат на шаг
\f С Перевод страницы (формата)
\n A Перевод строки
D Возврат каретки
\t   Горизонтальная табуляция
\v   Вертикальная табуляция
\\ 5C Обратная косая черта
\’   Апостроф
\"   Кавычка
\? 3F Вопросительный знак
\0oo 0oo - восьмеричный код символа
\xdd dd xdd - шестнадцатеричный код символа

Операции и выражения

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

Операция – это действие, осуществляемое над операндами. Например:

 

2 + 3

Здесь операция сложения (+) выполняется над двумя операндами (2 и 3).

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

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

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

Ниже приведены операции характерные для рассмотренных выше арифметических типов данных. Другие операции будут рассмотрены по мере изучения соответствующих типов данных.

 

Унарные операции
Операция Описание
++   увеличение на 1 (инкремент)
-- уменьшение на 1 (декремент)
sizeof размер объекта или тапа данных в байтах
~ поразрядное отрицание
! логическое отрицание
- арифметическое отрицание (унарный минус)
+ унарный плюс
(тип) явное преобразование типов

 

Бинарные операции
Операция Описание
* умножение
/ деление
% остаток от деления
+ сложение
- вычитание
<< сдвиг влево
>> сдвиг вправо
< меньше
<= меньше или равно
> больше
>= больше или равно
== равно
!= не равно
& поразрядная конъюнкция (И)
^ поразрядное исключающее ИЛИ
| поразрядная дизъюнкция (ИЛИ)
&& логическое И
|| логическое ИЛИ

 

Особое значение имеет операция присвоения и ее модификации:

 

Операция Краткое описание
= присваивание
*= умножение с присваиванием
/= деление с присваиванием
%= остаток отделения с присваиванием
+= сложение с присваиванием
-= вычитание с присваиванием
<<= сдвиг влево с присваиванием
>>= сдвиг вправо с присваиванием
&= поразрядное И с присваиванием
|= поразрядное ИЛИ с присваиванием
^= поразрядное исключающее ИЛИ с присваиванием

 

Тернарная операция
Операция Описание
?: условная операция

 

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

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

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

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

 

int a = 5;

double b = 7.6;

 

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

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

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

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

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

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

1. Все данные типов char и short int преобразуются к типу 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.14 int (3.14)

(double) a или double (a)

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

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

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

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

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

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

 

short a = 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

 

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

 

double d = 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)

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

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

Операция присваивания

Одна из наиболее часто используемых операций. Формат операции:

 

<Переменная> = <Выражение>

| |

Операнд 1 Операнд 2

Например: a = b; b = 3 * a; c = 1.234;

Сначала вычисляется значение выражения с правой стороны, а затем полученное значение присваивается переменной в левой части операции (значение выражения записывается в область памяти переменной). Старое значение переменной при этом безвозвратно теряется.

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

 

#include <iostream>

using namespace std;

Int main()

{

int i = 100000, k;

short j = 10000, m;

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

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

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

k = 12500;

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

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

double d = 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; // С потерей данных

/* На экран буде



Поделиться:


Последнее изменение этой страницы: 2017-02-07; просмотров: 183; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.139.233.43 (0.276 с.)