Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015

Здесь есть возможность читать онлайн «Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Год выпуска: 0101, Издательство: Вильямс, Жанр: Старинная литература, на русском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

Язык программирования C. Лекции и упражнения (6-е изд.) 2015: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Язык программирования C. Лекции и упражнения (6-е изд.) 2015»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

Язык программирования C. Лекции и упражнения (6-е изд.) 2015 — читать онлайн бесплатно полную книгу (весь текст) целиком

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Язык программирования C. Лекции и упражнения (6-е изд.) 2015», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Третья строка демонстрирует, что происходит при попытке преобразования в символ значения, которое больше 255. В нашей системе тип short int занимает 2 байта, а тип char — 1 байт. Когда функция printf() выводит 336 с использованием спецификатора %с, она просматривает только один байт из двух, задействованных для хранения 336. Такое усечение (рис. 4.8) равнозначно делению целого числа на 256 с сохранением только остатка. В этом случае остаток равен 80, что представляет собой ASCII-значение символа Р. Формально можно сказать, что число интерпретируется как результат деления по модулю 256, что означает использование остатка от деления числа на 256.

Рис 48 Интерпретация числа 336 как символа В заключение мы попытались - фото 97

Рис. 4.8. Интерпретация числа 336 как символа

В заключение мы попытались вывести в своей системе целое число (65618), превышающее максимально допустимое значение типа short int (32767). И снова компьютер применил деление по модулю. Число 65618 в силу своего размера хранится в нашей системе как 4-байтовое значение int. Когда оно выводится с применением спецификатора %hd, функция printf() использует только последние 2 байга, которые равносильны остатку от деления на 65536. В этом случае остаток равен 82. Остаток, находящийся между 32767 и 65536, с учетом способа хранения отрицательных чисел выводился бы как отрицательное число. В системах с другими размерами целых чисел общее поведение было бы таким же, но с другими числовыми значениями.

140 Глава 4

Когда вы начнете смешивать целочисленные типы и типы с плавающей запятой, результаты станут еще более причудливыми. Для примера рассмотрим программу, приведенную в листинге 4.12.

Листинг 4.12. Программа floatcnv.c

В нашей системе код из листинга 412 сгенерировал следующий вывод 30е00 - фото 98

В нашей системе код из листинга 4.12 сгенерировал следующий вывод:

3.0е+00 3.0е+00 3.1е+46 1.7е+266

2000000000 1234567890

0 1074266112 0 1074266112

Первая строка вывода показывает, что применение спецификатора %е не вызывает преобразование целого числа в число с плавающей запятой. Давайте посмотрим, что происходит при попытке вывода переменной n3 (типа long) с использованием спецификатора %е. Во-первых, спецификатор %е заставляет функцию printf() ожидать значение типа double, которое в нашей системе является 8-байтовым. Когда функция printf() исследует переменную n3, представленную в нашей системе 4-байтовым значением, она просматривает также смежные 4 байта памяти. Таким образом, функция анализирует 8-байтовый блок, в котором содержится действительное значение n3. Во-вторых, она интерпретирует биты этого блока как число с плавающей запятой. Например, некоторые биты, будут трактоваться в качестве показателя степени. Поэтому, даже если бы значение n3 содержало правильное количество битов, для спецификаторов %е и %ld они бы интерпретировались по-разному. Конечный результат оказывается бессмысленным.

Первая строка вывода также иллюстрирует то, что упоминалось ранее — при передаче в виде аргумента функции printf() значение float преобразуется в тип double. В данной системе тип float занимает 4 байта, но переменная nl была расширена до 8 байтов, чтобы функция printf() смогла корректно отобразить ее значение.

Вторая строка вывода показывает, что функция printf() может правильно выводить значения n3 и n4, если указан корректный спецификатор.

Третья строка вывода демонстрирует, что даже правильный спецификатор может приводить к ложным результатам, если оператор printf() содержит несоответствия где-то в другом месте. Как и можно было ожидать, попытка вывода значения с плавающей запятой с применением спецификатора %ld оказывается неудачной, однако в данном случае неудачу терпит и попытка вывода значения типа long с использованием спецификатора % &ld! Проблема кроется в способе передачи информации функции. Точные детали отказа при выводе зависят от реализации, но во врезке “Передача аргументов” обсуждается поведение в типичной системе.

Символьные строки и форматированный ввод-вывод 141

Передача аргументов

Механизм передачи аргументов зависит от реализации. Вот как передача аргументов происходит в нашей системе. Вызов функции выглядит следующим образом:

printf ("%ld %ld %ld %ld\n", nl, n2, n3, n4);

Этот вызов сообщает компьютеру о том, что ему передаются значения переменных nl, n2, n3 и n4. Ниже описан один из распространенных способов обработки этой ситуации. Программа помещает значения в область памяти, которая называется стеком Когда компьютер помещает эти значения в стек, он руководствуется типами переменных, а не спецификаторами преобразования. Следовательно, для nl он выделяет в стеке 8 байтов (float преобразуется в double). Подобным же образом для переменной n2 отводится еще 8 байтов, после чего по 4 байта выделяется для переменных n3 и n4. Затем управление передается функции printf(). Эта функция читает значения из стека, но делает это согласно спецификаторам преобразования. Спецификатор %ld указывает, что функция printf() должна прочитать 4 байта, поэтому она считывает первые 4 байта в стеке в качестве своего первого значения. Прочитанные 4 байта представляют собой первую половину nl, которая интерпретируется как целочисленное значение long. Следующий спецификатор %ld обеспечивает чтение еще 4 байтов; это вторая половина nl, и она интерпретируется как второе целочисленное значение long (рис. 4.9). Аналогично третий и четвертый спецификаторы %ld приводят к чтению первой и второй половины n2 с последующей их интерпретацией в качестве еще двух целочисленных значений long, так что, хотя для переменных n3 и n4 указаны корректные спецификаторы, функция printf() читает не те байты, которые нужны.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Похожие книги на «Язык программирования C. Лекции и упражнения (6-е изд.) 2015»

Представляем Вашему вниманию похожие книги на «Язык программирования C. Лекции и упражнения (6-е изд.) 2015» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


Отзывы о книге «Язык программирования C. Лекции и упражнения (6-е изд.) 2015»

Обсуждение, отзывы о книге «Язык программирования C. Лекции и упражнения (6-е изд.) 2015» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x