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

int x = f;

cout << x << ' ' << f << '\n';

Значение переменной x будет равно 2. Оно не будет равным 3, как вы могли подумать, если применили “правило округления 4/5”. В языке C++ преобразование типа float в тип int сопровождается усечением, а не округлением.

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

Язык C++ не решит эту проблему за вас. Рассмотрим пример.

void f(int i, double fpd)

{

 char c = i;      // да: тип char действительно представляет

                  // очень маленькие целые числа

 short s = i;     // опасно: переменная типа int может

                  // не поместиться

                  // в памяти, выделенной для переменной

                  // типа short

 i = i+1;         // что, если число i станет максимальным?

 long lg = i*i;   // опасно: переменная типа long не может

                  // вместить результат

 float fps = fpd; // опасно: большее число типа large может

                  // не поместиться в типе float

 i = fpd;         // усечение: например, 5.7 –> 5

 fps = i;         // можно потерять точность (при очень

                  // больших целых)

}

void g()

{

  char ch = 0;

  for (int i = 0; i<500; ++i)

    cout << int(ch++) << '\t';

}

Если сомневаетесь, поэкспериментируйте! Не следует отчаиваться и в то же время нельзя просто читать документацию. Без экспериментирования вы можете не понять содержание весьма сложной документации, связанной с числовыми типами.

ПОПРОБУЙТЕ

Выполните функцию g(). Модифицируйте функцию f() так, чтобы она выводила на печать переменные c, s, i и т.д. Протестируйте программу на разных значениях.

  Представление целых чисел и их преобразование еще будет рассматриваться в разделе 25.5.3. По возможности ограничивайтесь немногими типами данных, чтобы минимизировать вероятность ошибок. Например, используя только тип double и избегая типа float, мы минимизируем вероятность возникновения проблем, связанных с преобразованием doublefloat. Например, мы предпочитаем использовать только типы int, double и complex (см. раздел 24.9) для вычислений, char — для символов и bool — для логических сущностей. Остальные арифметические типы мы используем только при крайней необходимости.

<p id="AutBody_Root463"><strong>24.2.1. Пределы числовых диапазонов</strong></p>

  Каждая реализация языка C++ определяет свойства встроенных типов в заголовках , и , чтобы программисты могли проверить пределы диапазонов, установить сигнальные метки и т.д. Эти значения перечислены в разделе Б.9.1. Они играют очень важную роль для создания низкоуровневых инструментов. Если они вам нужны, значит, вы работаете непосредственно с аппаратным обеспечением, хотя существуют и другие приложения. Например, довольно часто возникают вопросы о тонкостях реализации языка, например: “Насколько большим является тип int?” или “Имеет ли знак тип char?” Найти определенные и правильные ответы в системной документации бывает трудно, а в стандарте указаны только минимальные требования. Однако можно легко написать программу, находящую ответы на эти вопросы.

cout << "количество байтов в типе int: " << sizeof(int) << '\n';

cout << "наибольшее число типа int: " << INT_MAX << endl;

cout << "наименьшее число типа int: " << numeric_limits::min()

     << '\n';

if (numeric_limits::is_signed)

  cout << "тип char имеет знак n";

else

  cout << "тип char не имеет знака\n";

cout << "char с минимальным значением: "

     << numeric_limits::min() <<'\n';

cout << "минимальное значение типа char: "

     << int(numeric_limits::min()) << '\n';

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

Эти пределы также могут быть полезными для выявления переполнения.

<p id="AutBody_Root464"><strong>24.3. Массивы</strong></p>
Перейти на страницу:

Похожие книги

Programming with POSIX® Threads
Programming with POSIX® Threads

With this practical book, you will attain a solid understanding of threads and will discover how to put this powerful mode of programming to work in real-world applications. The primary advantage of threaded programming is that it enables your applications to accomplish more than one task at the same time by using the number-crunching power of multiprocessor parallelism and by automatically exploiting I/O concurrency in your code, even on a single processor machine. The result: applications that are faster, more responsive to users, and often easier to maintain. Threaded programming is particularly well suited to network programming where it helps alleviate the bottleneck of slow network I/O. This book offers an in-depth description of the IEEE operating system interface standard, POSIX (Portable Operating System Interface) threads, commonly called Pthreads. Written for experienced C programmers, but assuming no previous knowledge of threads, the book explains basic concepts such as asynchronous programming, the lifecycle of a thread, and synchronization. You then move to more advanced topics such as attributes objects, thread-specific data, and realtime scheduling. An entire chapter is devoted to "real code," with a look at barriers, read/write locks, the work queue manager, and how to utilize existing libraries. In addition, the book tackles one of the thorniest problems faced by thread programmers-debugging-with valuable suggestions on how to avoid code errors and performance problems from the outset. Numerous annotated examples are used to illustrate real-world concepts. A Pthreads mini-reference and a look at future standardization are also included.

David Butenhof

Программирование, программы, базы данных