- •Алфавит.
- •Объявления и определения
- •Структура и компоненты простой программы
- •Текст программы и препроцессор.
- •Структура программы.
- •Функция форматированного вывода.
- •Программы печати предельных констант.
- •Применимость вещественных данных.
- •Выделение лексем из текста программы.
- •2.2. Элементарные средства программирования Деление операторов языка Си на группы.
- •Программа оценки машинного нуля.
- •Трассировочная таблица
- •Переключатели
- •Ввод данных.
- •Вычисление объема цилиндра.
- •Операторы цикла
- •Три формы операторов цикла.
- •Приближенное значение экспоненты.
- •Оператор break.
- •Сумма отрезка степенного ряда.
- •Оператор continue.
- •Суммирование положительных чисел.
- •2.4. Массивы и вложение операторов цикла Массивы и переменные с индексами.
- •Вычисление среднего и дисперсии.
- •Упорядочение в одномерных массивах.
- •Инициализация массивов.
- •Моделирование многомерных массивов.
- •Ввод и вывод
- •7.1. Потоковый ввод-вывод
- •7.1.1. Открытие и закрытие потока
- •7.1.2. Стандартные файлы и функции для работы с ними
- •Ввод-вывод отдельных символов.
- •Ввод-вывод строк.
- •Форматный ввод-вывод.
- •Спецификаторы форматной строки для функции форматного вывода
- •Спецификаторы форматной строки для функции форматного ввода
- •Работа с файлами на диске
- •Двоичный (бинарный) режим обмена с файлами.
- •Строковый обмен с файлами.
- •Позиционирование в потоке.
- •Трехъязычный словарь "Цифры
- •7.2. Ввод-вывод нижнего уровня
- •7.2.1. Открытие / закрытие файла
- •7.2.2. Чтение и запись данных
- •7.2.3. Произвольный доступ к файлу
- •Теоретические положения Управление экраном в текстовом режиме в ms dos
- •Основные функции работы в текстовом режиме
- •2.5. Функции Определение функций.
- •Функция для вычисления объема цилиндра.
- •Функция для вычисления скалярного произведения векторов.
- •Обращение к функции и ее прототип.
- •Вычисление объема цилиндра
- •Вычисление площади треугольника.
- •Скалярное произведение векторов.
- •Препроцессорные средства
- •Глава 6. Структуры и объединения
- •6.1. Структурные типы и структуры Производные типы.
- •Структурный тип.
- •Определение структур.
- •Выделение памяти для структур.
- •Инициализация и присваивание структур.
- •Доступ к элементам структур.
- •Модули:
- •Некоторые понятия:
Программы печати предельных констант.
Программы печати предельных констант. Введенных средств препроцессора и языка вполне достаточно для программы, выводящей на печать (на экран дисплея) значения констант, определяющие в конкретной системе (для конкретного компилятора) пределы изменения данных разных типов. Таблица стандартных обозначений предельных констант есть в Приложении 2. В главе 1 (§1.3) приведены некоторые из них. Там же, говоря об именованных константах, мы отметили, что среди стандартных заголовочных файлов компилятора всегда есть файлы limits.h и float.h, включающие препроцессорное определение предельных констант. Следующая программа печатает некоторые из значений предельных констант для целых типов, определенных конкретной реализацией компилятора с языка Си.
Результат выполнения программы с компилятором Turbo С:
В вызовах функции printf( ) нужно обратить внимание на спецификации преобразования. Все константы целочисленные, поэтому используется спецификатор 'd'. Для величин типа long потребовался модификатор 'l', т.е. константы LONG_MIN и LONG_MAX выводятся с использованием спецификаций преобразования %ld. Во всех спецификациях преобразования отсутствуют сведения о длине изображения выводимых значений. Количество позиций в изображениях констант зависит от их значений. Управляющие последовательности '\n' и '\t' обеспечивают при выводе соответственно переходы на новые строки и табуляцию.
Для вывода вещественных значений с мантиссой и порядком в форматной строке функции printf( ) нужно использовать спецификацию %е. Следующая программа выводит на экран значения некоторых из предельных вещественных констант:
Результаты выполнения программы с компилятором Turbo С:
Отметим применение символа табуляции '\t' для размещения информации, выводимой на дисплей. Больше в использовании функции printf( ), кроме спецификации %е, ничего нового нет. Стоит пояснить смысл напечатанных констант. FLT_EPSILON и DBL_EPSILON - максимальные значения типов float и double, сумма каждого из которых со значением 1.0 не отличается от 1.0. Предельные константы FLT_EPSILON и DBL_EPSILON называют "машинными нулями" относительно вещественного значения 1.0. FLT_MIN, FLT_MAX и DBL_MAX - предельные значения для вещественных данных. FLT_MANT_MG, DBL_MANT_DIG - количество двоичных цифр (бит) в мантиссах соответственно чисел типа float и double.
Применимость вещественных данных.
Применимость вещественных данных. Даже познакомившись с различиями в диапазонах представления вещественных чисел, начинающий программист не сразу осознает различия между типами float, double и long double. Сразу бросается в глаза разное количество байтов, отводимых в памяти для вещественных данных перечисленных типов. На IBM PC:
• для float - 4 байта;
• для double - 8 байт;
• для long double - 10 байт.
Обратив внимание на значения предельных констант, отмечают (см. Приложение 2), что максимальные значения, которые можно представить вещественными числами, определены константами:
FLT_MAX приблизительно равно 1Е+37 (для float);
DBL_MAX приблизительно равно 1Е+308 (для double).
Затем обращают внимание на количество верных десятичных цифр в мантиссах:
FLT_DIG равно 6 (для float);
DBL_DIG равно 10 (для double).
Наконец, оценят минимальные нормализованные числа:
FLTJMIN приблизительно равно 1Е-37 (для float);
DBL_MIN приблизительно равно 1Е-308 (для double).
Можно и дальше продолжать сравнение констант, перечисленных в описании языка (см. Приложение 2), но нужно сделать выводы относительно применимости вещественных констант и переменных разных типов. По умолчанию все константы, не относящиеся к целым типам, принимают тип double. У программиста это соглашение часто вызывает недоумение - а не лучше ли всегда работать с вещественными данными типа float и только при необходимости переходить к double или long double? Ведь значения больше 1Е+38 и меньше 1Е-38 встречаются довольно редко.
Следующая программа (предложена С.М. Лавреновым) иллюстрирует опасности, связанные с применением данных типа float даже в несложных арифметических выражениях:
Результат выполнения программы:
Если в той же программе переменной а присвоить значение 100.0, то результат будет еще хуже:
c= 0.000000.
Таким образом, запрограммированное с использованием переменных типа float несложное алгебраическое выражение
никак "не хочет" вычисляться и принимать свое явное теоретическое единичное значение.
Если заменить в программе только одну строку, т.е. так определить переменные:
значение выражения вычисляется совершенно точно:
Приведенный пример и общие положения вычислительной математики заставляют существенно ограничить применение переменных типа float. Тип float можно выбирать для представления исходных данных или окончательных результатов, получаемых в программе. Однако применение данных типа float в промежуточных вычислениях (особенно в итерационных алгоритмах) следует ограничить и всегда использовать double либо long double.
К сожалению, ни double, ни long double не снимают полностью проблем конечной точности представления вещественных чисел в памяти ЭВМ. Существенное различие в порядках значений операндов арифметических выражений может привести к подобным некорректным результатам и при использовании типов double и long.