Язык Си - [25]

Шрифт
Интервал

Использование функции 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 некоторого символа. Например оператор

printf(" %c%d\n" , ' А', ' А');

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

A 65

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

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

printf(" %d %c\n" , 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 %d\n" , 65616, 65616);

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

65616   80

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

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

Применение функции scanf( ) 

     Поскольку в дальнейшем мы будем пользоваться функция scanf( ) лишь эпизодически, мы рассмотрим здесь только основные особенности ее применения.

     Так же как для функции printf( ), для функции scanf( ) указываются управляющая строка и следующий за ней список аргументов. Основное различие двух этих функций заключается в особенности данного списка. Функция printf( ) использует имена переменных константы и выражения, в то время как функция scanf( ) - только указатели на переменные. К счастью, при применении этой функции мы ничего не должны знать о таких указателях. Необходимо помнить только два правила:

     1. Если вам нужно ввести некоторое значение и присвоить его переменной одного из основных типов, то перед именем nepеменной требуется писать символ


Еще от автора Митчел Уэйт
Язык программирования C [Лекции и упражнения, 6-е изд.]

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Рекомендуем почитать
Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Программное обеспечение и его разработка

Автор книги — американский специалист по программированию, один из руководителей фирмы IBM, в своей книге делает попытку изложить общие проблемы создания программного обеспечения, его сопровождения и использования. Особенно подробно рассматриваются все фазы разработки программ разных типов. Изложение ясное, удачно иллюстрировано примерами.Для программистов разной квалификации и пользователей ЭВМ.fb2: ВНИМАНИЕ. В тексте присутствуют таблицы. Рекомендуется читать файл с помощью программы, поддерживающей их отображение.


Пользовательские истории. Искусство гибкой разработки ПО

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


Идиомы и стили С++

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Симуляция частичной специализации

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Тонкости дизассемблирования

Очень часто под рукой не оказывается ни отладчика, ни дизассемблера, ни даже компилятора, чтобы набросать хотя бы примитивный трассировщик. Разумеется, что говорить о взломе современных защитных механизмов в таких условиях просто смешно, но что делать если жизнь заставляет?..