Чтение онлайн

на главную

Жанры

Программирование. Принципы и практика использования C++ Исправленное издание
Шрифт:

Понятие типа является основным в языке С++ и большинстве других языков программирования. Рассмотрим типы пристальнее и немного более строго. Особое внимание уделим типам объектов, в которых хранятся данные на этапе вычислений. Все это сэкономит нам время в ходе долгих вычислений и позволит избежать некоторых недоразумений.

Тип — определяет набор возможных значений и операций, выполняемых над объектом.

Объект — участок памяти, в котором хранится значение определенного типа.

Значение — набор битов в памяти, интерпретируемый в соответствии с типом.

Переменная — именованный объект.

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

Определение — объявление, выделяющее память

для объекта.

Неформально объект можно представить в виде ящика, в который можно положить значения определенного типа. В ящике для объектов типа

int
можно хранить только целые числа, например 7, 42 и –399. В ящике для объектов типа
string
можно хранить символьные строки, например "
Interoperability
", "
tokens: @#$%^&*
" и "
Old MacDonald had a farm
". Графически это можно представить так:

Представление объекта типа

string
немного сложнее, чем объекта типа
int
, так как тип
string
хранит количество символов в строке. Обратите внимание на то, что объект типа
double
хранит число, а объект типа
string
— символы. Например, переменная
x
содержит число
1.2
, а переменная
s2
— три символа: '
1
', '
.
' и '
2
'. Кавычки вокруг символа и строковых литералов в переменных не хранятся.

Все переменные типа

int
имеют одинаковый размер; иначе говоря, для каждой переменной типа
int
компилятор выделяет одинаковое количество памяти. В типичном настольном компьютере этот объем равен 4 байтам (32 бита). Аналогично, объекты типов
bool
,
char
и
double
имеют фиксированный размер. В настольном компьютере переменные типа
bool
и
char
, как правило, занимают один байт (8 бит), а переменная типа
double
— 8 байт. Обратите внимание на то, что разные типы объектов занимают разное количество памяти в компьютере. В частности, переменная типа
char
занимает меньше памяти, чем переменная типа
int
, а переменная типа
string
отличается от переменных типов
double
,
int
и
char
тем, что разные строки занимают разное количество памяти.

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

12.5
? Мы не знаем. Это может быть
12.5
долл.,
12.5
см или
12.5
галлонов. Только после того, как мы припишем числу
12.5
единицу измерения, оно приобретет конкретный смысл. Например, один и тот же набор битов в памяти может представлять число
120
, если его интерпретировать как переменную типа
int
, и символ
'x'
, если трактовать его как объект типа
char
. Если взглянуть на него как на объект типа
string
, то он вообще потеряет смысл и попытка его использовать приведет к ошибке, возникшей в ходе выполнения программы. Эту ситуацию можно проиллюстрировать следующим образом (здесь 1 и 0 означают значения битов в памяти).

Этот набор битов, записанных в участке памяти (слове), можно прочитать как переменную типа

int (120)
или
char ('x')
, если учитывать только младшие биты. Бит — это единица памяти компьютера, которая может хранить либо 0, либо 1.

Смысл двоичных

чисел описан в разделе А.2.1.1.

3.9. Типовая безопасность

Каждый объект в ходе определения получает тип. Программа — или часть программы — является безопасной с точки зрения использования типов (type-safe), если объекты используются только в соответствии с правилами, предусмотренными для их типов. К сожалению, существуют операции, которые не являются безопасными с этой точки зрения. Например, использование переменной до ее инициализации не считается безопасным.

int main

{

double x; // мы забыли проинициализировать переменную х:

// ее значение не определено

double y = x; // значение переменной y не определено

double z = 2.0+x; // смысл операции + и значение переменной z

// не определены

}

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

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

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

3.9.1. Безопасные преобразования

В разделе 3.4 мы видели, что нельзя непосредственно складывать объекты типа

char
или сравнивать объекты типов
double
и
int
. Однако в языке С++ это можно сделать косвенным образом. При необходимости объект типа
char
можно преобразовать в объект типа
int
, а объект типа
int
— в объект типа
double
. Рассмотрим пример.

char c = 'x';

int i1 = c;

int i2 = 'x';

Здесь значения переменных

i1
и
i2
равны
120
, т.е. 8-битовому ASCII коду символа
'x'
. Это простой и безопасный способ получения числового представления символа. Мы называем это преобразование типа
char
в тип
int
безопасным, поскольку при этом не происходит потери информации; иначе говоря, мы можем скопировать результат, хранящийся в переменной типа
int
, обратно в переменную типа
char
и получить исходное значение.

char c2 = i1;

cout << c << ' ' << i1 << ' ' << c2 << '\n';

Этот фрагмент программы выводит на экран следующий результат:

x 120 x

В этом смысле — то, что значение всегда преобразуется в эквивалентное значение или (для типа

double
) в наилучшее приближение эквивалентного значения, — такие преобразования являются безопасными.

Поделиться:
Популярные книги

Идеальный мир для Лекаря 20

Сапфир Олег
20. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 20

Пропала, или Как влюбить в себя жену

Юнина Наталья
2. Исцели меня
Любовные романы:
современные любовные романы
6.70
рейтинг книги
Пропала, или Как влюбить в себя жену

Снегурка для опера Морозова

Бигси Анна
4. Опасная работа
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Снегурка для опера Морозова

Восхождение Примарха 7

Дубов Дмитрий
7. Восхождение Примарха
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Восхождение Примарха 7

Хуррит

Рави Ивар
Фантастика:
героическая фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Хуррит

Рождение победителя

Каменистый Артем
3. Девятый
Фантастика:
фэнтези
альтернативная история
9.07
рейтинг книги
Рождение победителя

Ты не мой Boy 2

Рам Янка
6. Самбисты
Любовные романы:
современные любовные романы
короткие любовные романы
5.00
рейтинг книги
Ты не мой Boy 2

Метатель. Книга 2

Тарасов Ник
2. Метатель
Фантастика:
боевая фантастика
попаданцы
рпг
фэнтези
фантастика: прочее
постапокалипсис
5.00
рейтинг книги
Метатель. Книга 2

Право налево

Зика Натаэль
Любовные романы:
современные любовные романы
8.38
рейтинг книги
Право налево

Имя нам Легион. Том 2

Дорничев Дмитрий
2. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 2

Сумеречный стрелок 8

Карелин Сергей Витальевич
8. Сумеречный стрелок
Фантастика:
городское фэнтези
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Сумеречный стрелок 8

Кодекс Охотника. Книга VIII

Винокуров Юрий
8. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга VIII

Сильнейший ученик. Том 2

Ткачев Андрей Юрьевич
2. Пробуждение крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сильнейший ученик. Том 2

Последняя Арена 4

Греков Сергей
4. Последняя Арена
Фантастика:
рпг
постапокалипсис
5.00
рейтинг книги
Последняя Арена 4