Книга: Язык Си - руководство для начинающих

Использование функции printf( ) для преобразования данных

Использование функции printf( ) для преобразования данных

     Здесь мы снова займемся выводом на печать целых чисел. Поскольку мы уже осведомлены о полях, то не будем заботиться об использовании символа /, чтобы отмечать их начало и конец.

main( )

{

printf(" %dn", 336);

printf(" %on", 336);

printf(" %xn", 336);

printf(" %dn",  -336);

printf(" %un",  -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 некоторого символа. Например оператор

printf(" %c%dn" , ' А', ' А');

выдаст следующий результат:

A 65

А - это буква, а 65 - десятичный код ASCII символа А. Мы могли бы использовать спецификацию , если бы хотели получить восьмеричный код ASCII символа А.

     Все вышесказанное дает хороший способ нахождения кодов ASCII для различных символов и наоборот. Вполне возможно, конечно, что вы предпочтете ему поиск кодов в приложении Ж. Что произойдет, если вы попробуете преобразовать число, больше 255, в символ? Следующая строка и результат ее выполнения дадут ответ на этот вопрос:

printf(" %d %cn" , 336, 336);

336 P

     Десятичный код ASCII символа Р равен 80, а 336 - это 256 + 80. Данное число, очевидно, интерпретируется по модулю 256. (Это математический термин, обозначающий остаток от деления числа на 256.) Другими словами, всякий раз при получении чис ла, кратного 256, отсчет начинается сначала, и 256 рассматривается как 0, 257 - как 1, 511 - как 255, 512 - как 0, 513 - как 1 и т. д.

     И, наконец, попытаемся напечатать число (65616), превышающее максимальное значение, которое могут принимать данные типа int в нашей системе (32767):

printf(" %1d %dn" , 65616, 65616);

Результат будет выглядеть так:

65616   80

     Мы снова видим, что действия выполняются по "модулю" На этот раз счет ведется группами по 65536. Числа между 32767 и 65536 будут выводиться на печать как отрицательные из-за способа их представления в памяти машины. Системы с разными размера ми ячеек памяти, отводимых под данные целого типа, ведут себя в общем одинаково, но при этом дают разные числовые значения.

     Мы не исчерпали всех возможных комбинаций данных и спецификаций преобразования, поэтому вы можете пытаться экспериментировать сами. Но будет лучше, конечно, если вы сможете за ранее предсказать результат, который будет получен при печати данных, когда используется какая-нибудь спецификация преобразования, выбранная вами.

Оглавление книги


Генерация: 1.191. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз