logo
Харви Дейтел, Пол Дейтел Как программировать на С++ / 02-Deitel-Стр-115-214

188 Глава 3

математическая библиотечная функция sqrt может быть вызвана с аргумен­том целого типа, даже если функция прототип в math.h определяет аргумент типа double, и при этом функция будет работать правильно. Оператор

cout « sqrt(4);

правильно вычисляет sqrt(4), и печатает значение 2. Прототип функции заставляет компилятор преобразовать целое значение 4 в значение 4.0 типа double прежде, чем значение будет передано в sqrt. Вообще, значения аргумен­тов, которые первоначально не соответствуют типам параметров в прототипе функции, преобразуются в подходящий тип перед вызовом функции. Эти преобразования могут привести к неверным результатам, если не руководст­воваться правилами приведения типов С++. Правила приведения определяют, как типы могут быть преобразованы в другие типы без потерь. В приведенном выше примере sqrt тип int автоматически преобразуется в double без изменения его значений. Однако double преобразуется в int с отбрасыванием дробной части значения double. Преобразование больших целых типов в малые целые типы (например, long в short) может также привести к изменению значений.

Правила приведения типов применяются к выражениям, содержащим значения двух или более типов данных; такие выражения относятся к вы­ражениям смешанного типа. Тип каждого значения в выражении смешан­ного типа приводится к «наивысшему» типу, имеющемуся в выражении (на самом деле создается и используется временная копия выражения — истин­ные значения остаются неизменными). На рис. 3.5 перечислены встроенные типы данных в порядке следования от высших типов к низшим.

Преобразование значений к низшему типу может привести к неверным значениям. Поэтому значения могут преобразовываться к низшему типу толь­ко путем явного присваивания значения переменной низшего типа, либо с помощью операции приведения к типу. Значения аргументов функции пре­образуются к типам параметров в прототипе функции так, как если бы они были непосредственно присвоены переменным этих типов. Если наша функ­ция square, которая использует параметр целого типа (рис. 3.3), вызывается с аргументом с плавающей точкой, аргумент преобразуется к типу int (низ­шему типу) и squre обычно возвращает неверное значение. Например, square(4.5) возвратит 16 вместо 20.25.

Типичная ошибка программирования 3.10

Преобразование от высшего типа в иерархии типов к низшему может изменить значение данных.

Типичная ошибка программирования 3.11

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

Замечание по технике программирования 3.10

Прототип функции, размещенный вне описания какой-то другой функции, относится ко всем вызовам данной функции, появляющимся после этого прототипа в данном файле. Прототип функции, размещенный внутри описания некоторой функции, от­носится только к вызовам внутри этой функции.

Функции 189

Типы данных

long double

double

float

unsigned long int

(синоним unsigned

long)

long int

(синоним long)

unsigned int

(синоним unsigned)

int

unsigned short int

(синоним unsigned

short)

short int

(синоним short)

unsigned char

char

Рис. 3.5. Иерархия преобразований встроенных типов данных