Рассмотрим теперь некоторые форматы, соответствующие данным с плавающей точкой. Допустим, у нас имеется следующая программa:
main( )
{
printf(" /%f/\n" , 1234.56);
printf(" /%e/\n" , 1234.56);
printf(" /%4.2f/\n" , 1234.56);
printf(" /%3.1f/\n", 1234.56);
printf(" /%10.3f/\n" , 1234.56);
printf(" /%10.3e/\n" , 1234.56);
}
На этот раз результат работы программы будет выглядеть так
/1234.560059/
/1.234560E+03/
/1234.56/
/1234.6/
/ 1234.560/
/ 1.234E+03/
Мы снова начинаем с варианта, выбранного по умолчанию, т. е. сo спецификации %f. В этом случае имеется две величины, значене которых используются по умолчанию: ширина поля и число цифр справа от десятичной точки. Вторая величина задает шесть цифр, ширина поля берется такой, чтобы в нем могло поместиться число. Заметим, что печатаемое число несколько отличается от исходного. Это происходит потому, что на печать выводится 10 цифр, в то время как числа с плавающей точкой в нашей системе изображаются приблизительно с точностью до 6 или 7 цифр.
Рассмотрим вариант по умолчанию для спецификации %е. Как мы видим, при ее использовании печатается одна цифра слева от десятичной точки и шесть справа. В результате получается слишком много цифр! Чтобы избежать этого, необходимо задать число цифр справа от десятичной точки, и последние четыре опера тора программы реализуют как раз указанную возможность. Обратите внимание на то, как четвертый и шестой операторы производят округление выводимых данных.
Теперь исследуем некоторые варианты строк. Рассмотрим пример:
#define BLURB "Выдающееся исполнение"
main( )
{
printf(" /%2s/\n" , BLURB);
printf(" /'%25.s/\n" , BLURB);
printf(" /'%25.5s/\n" , BLURB);
printf(" /% - 25.5s/\n" , BLURB);
}
Boт результат работы программы:
/Выдающееся исполнение!/
/ Выдающееся исполнение!/
/ Выдаю/ /Выдаю /
Обратите внимание на то, как поле расширяется для того, чтобы поместились все указанные символы. Заметим также, как спецификация точности ограничивает число символов, выводимых на ПЕЧАТЬ. Символы .5 в спецификации формата указывают функции printf( ) на необходимость напечатать только пять символов.
Теперь вы ознакомились с некоторым количеством примеров. А знаете ли вы, как подготовить оператор печати, чтобы напечатав нечто вроде следующей фразы:
Семья NAME, возможно, лишь на XXX.XX долларов богаче!
Здесь NAME и ХХХ.ХХ представляют значения соответствующих переменных в программе, скажем name[40] и cash. Вот одно из решений:
printf(" Семья %s, возможно, лишь на %.2f долларов
богаче! \n", name, cash);
До сих пор мы без тени сомнения применяли спецификации преобразования для переменных разных типов, например, %f для типа float и т. д. Но, как мы уже видели в нашей программе поиска кода ASCII, для некоторого символа функцию printf() можно использовать также для преобразования данных из одного типа в другой. Мы не намерены, однако, терять чувство реальности и по прежнему будем работать с целыми типами.
Использование функции printf( ) для преобразования данных
Здесь мы снова займемся выводом на печать целых чисел. Поскольку мы уже осведомлены о полях, то не будем заботиться об использовании символа /, чтобы отмечать их начало и конец.
main( )
{
printf(" %d\n", 336);
printf(" %o\n", 336);
printf(" %x\n", 336);
printf(" %d\n", -336);
printf(" %u\n", -336);
}
В нашей системе результат будет выглядеть следующим образом
336
520
150
-336
-65200
Как вы, по-видимому, и ожидали, при использовании спецификации %d будет получено число 336 точно так же, как в примере, обсуждавшемся чуть выше. Но давайте посмотрим, что произойдет, когда вы "попросите" программу напечатать это десятичное целое число в восьмеричном коде. Она напечатает число 520, являющееся восьмеричным эквивалентом 336 (5х64+2х8+0х 1= 336). Аналогично при печати этого числа в шестнадцатеричном коде мы получим 150.
Таким образом, мы можем использовать спецификации, применяемые для функции printf( ) с целью преобразования десятичных чисел в восьмеричные или шестнадцатеричные и наоборот. Или же если вы захотите напечатать данные в желаемом для вас виде, то необходимо указать спецификацию %d для получения десятичных чисел, %о - для восьмеричных, а %х- для шестнадцатеричных. При этом не имеет ни малейшего значения, в какой форме число первоначально появилось в программе.
Сделаем еще несколько замечаний относительно вывода на печать. Печать числа -336 при использовании спецификации %d не вызывает никакого затруднения. При применении же спецификации %u (unsigned - беззнаковая) получаем число 65200, а не 336, как можно было бы ожидать. Причина получения такого результата лежит в способе представления отрицательных чисел в нашей системе. Здесь используется так называемый "дополнительный код". Числа от 0 до 32767 отображаются обычным образом, а от 32768 до 65535 представляют отрицательные числа, причем 65535 кодирует число -1, 65534 - число -2 и т. д. Поэтому числу -336 соответствует 65536, -336 = 65200. Этот метод применяется не во всех системах. Тем не менее отсюда следует вывод: не ожидайте, что спецификация преобразования %u приводит просто к отбрасыванию знака числа.
Сейчас мы переходим к обсуждению интересного примера, которого мы уже касались ранее, а именно к использованию функции printf() для нахождения кода ASCII некоторого символа. Например оператор