Язык Си - руководство для начинающих
Шрифт:
РИС. 4.6. Аргументы функции printf
Приведем еще пример:
printf(" Значение числа pi равно %f.\n", PI);
На этот раз список аргументов содержит только один элемент - символическую константу PI.
Мы видим, что в управляющей строке содержится информация двух различных видов:
1. Символы, печатаемые текстуально.
2. Идентификаторы данных, называемые также "спецификациями преобразования".
РИС. 4.7. Структура
Каждому аргументу из списка, следующего за управляющей строкой, должна соответствовать одна спецификация преобразования. Горе вам, если вы забудете это основное требование. Никогда не пишите, например, так:
printf("Количество слизняков %d, червяков %d.\n", scorel);
3десь отсутствует аргумент для второй спецификации преобразования %d. Способ проявления этой ошибки целиком зависит от вашей вычислительной системы, но в лучшем случае вы получите бессмыслицу.
Если вам нужно напечатать какую-нибудь фразу, то нет необходимости использовать спецификацию преобразования; если же требуется только вывести данные на печать, то можно обойтись и без использования комментария. Поэтому каждый из операторов, приведенных ниже, вполне приемлем.
printf("Прощай! Твое искусство слишком дорого для меня.\n");
printf(" %c%d\n" , '$', cost);
Заметим, что во втором примере первый аргумент из печатаемого списка является символьной константой, а не переменной.
Поскольку символ % используется в функции printf для идентифицирования спецификаций преобразования, возникает небольшая проблема в том случае, если вам нужно напечатать сам символ %, Если просто написать один знак %, то компилятор примет его за ошибочную спецификацию преобразования. Выходом из создавшейся ситуации служит довольно простое решение - писать два символа % подряд:
рс = 2*6;
printf("Только %d%% стряпни Салли было съедобно.\n", рс);
Результат работы программы будет выглядеть следующим образом:
Только 12% стряпни Салли было съедобно.
Модификаторы спецификации преобразования, используемые в функции printf
Мы можем несколько расширить основное определение спецификации преобразования, поместив модификаторы между знаком % и cимвoлoм, определяющим тип преобразования. В приводимой ниже таблице дан список тех символов, которые вы имеете право туда поместить. При использовании одновременно нескольких модификаторов они должны быть указаны в том порядке, в котором пере числены в таблице. Заметим, что при этом допускаются не все комбинации.
Модификатор | Значение |
---|---|
– | Аргумент будет печататься с левой позиции поля заданной ширины (как объяснено ниже). Обычно печать аргумента оканчивается в самой правой позиции поля. Пример: %-10d |
строка цифр | Задает минимальную ширину поля. Большее поле будет использоваться, если печатаемое число или строка не помещаются в исходном поле. Пример: %4d |
строка цифр | Определяет точность: для типов данных с плавающей точкой - число печатаемых цифр справа от десятичной точки; для символьных строк - максимальное число печатаемых символов Пример: %4.2f (две десятичные цифры для поля шириной в четыре символа) |
| | Соответствующий элемент данных имеет
|
Примеры
Посмотрим, как эти модификаторы работают. Начнем с того, что продемонстрируем влияние модификатора ширины поля на печать целого числа. Рассмотрим следующую программу:
main
{
printf("/%d/\n", 336);
printf("/%2d/\n", 336);
printf("/%10d/\n", 336);
printf("/%-10d/\n", 366);
}
Эта программа печатает одно и то же значение четыре раза, но используются при этом четыре различные спецификации преобразования. Мы вводим также символы /, чтобы вы могли видеть, где начинается и кончается каждое поле. Результат выполнения программы выглядит следующим образом:
/336/ /336/
/ 336 /336 /
Первая спецификация преобразования %d не содержит модификаторов. Мы видим, что поле печати здесь имеет ширину, равную количеству цифр данного целого числа. Это так называемый выбор "по умолчанию", т. е. результат действия компилятора в случае, если вы не дали ему никаких дополнительных инструкций. Вторая спецификация преобразования - %2d. Она указывает, что ширина поля должна равняться 2, но, поскольку число состоит из трех цифр, доле автоматически расширяется до необходимого размера. Следующая спецификация %10d показывает, что ширина поля равна 10. И действительно, между символами / имеется семь пробелов и три цифры, причем число сдвинуто к правому краю поля. Последняя спецификация %-10d также указывает ширину поля, равную 10, а знак - приводит к сдвигу всего числа к левому краю, как показано в приведенном выше примере. Когда вы привыкнете к этой системе обозначений, она покажется вам простой и вы сумеeте по вашему усмотрению менять вид выходной информации.
Рассмотрим теперь некоторые форматы, соответствующие данным с плавающей точкой. Допустим, у нас имеется следующая программ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 цифр.