Типы определены с использованием typedef. Например, в системе с 32-битовым int может применяться такое определение: typedef int int32_t;
Спецификаторы формата определены с помощью директив #define. Например, в системе, где используется приведенное выше определение int32_t, могут быть следующие определения:
#define PRId32 "d" // спецификатор вывода
#define SCNd32 "d" // спецификатор ввода
Имея эти определения, вы можете объявлять расширенные целочисленные переменные, вводить их значения и отображать следующим образом:
int32_t cd_sales; // 32-битовое целое число scanf("%" SCNd32, &cd_sales);
printf("Продажи компакт-дисков составили %10" PRId32 " единиц\n", cd_sales);
При необходимости применяется конкатенация строк, чтобы получить финальную управляющую строку. Таким образом, предыдущий код преобразуется к такому виду:
int cd_sales; // 32-битовое целое число
scanf("%d", &cd_sales);
printf("Продажи компакт-дисков составили %10d единиц\n", cd_sales);
Если вы перенесете первоначальный код в систему с 16-битовым int, то эта система может определить int32_t как long, PRId32 — как "ld", a SCNd32 — как "ld". Но вы могли бы использовать тот же самый код, зная, что в системе применяется 32битовый int.
В оставшейся части этого справочного раздела перечислены расширенные типы вместе со спецификаторами формата и макросами, представляющими предельные значения этих типов.
Типы с точной шириной
Один из наборов typedef идентифицирует типы с точными размерами. Общая форма выглядит как intw_t для типов со знаком и uintw t — для типов без знака, где N обозначает количество битов. Однако обратите внимание, что не все системы способны поддерживать все типы. Например, могла бы существовать система, для которой минимальной используемой единицей памяти является 16 битов; в такой системе не поддерживались бы типы int8_t и uint8_t. Макросы формата могут применять для типов со знаком либо d, либо i, поэтому PRH8 и SCNi8 также работают.
896 Приложение Б
Для типов без знака вы можете подставлять о, х или X для и, чтобы получить вместо %u спецификаторы %о, %х или %Х. Например, вы можете использовать PRIX32, чтобы вывести uint32_t в шестнадцатеричной форме. В табл. Б.VI.1 перечислены типы с точной шириной, спецификаторы формата и предельные значения.
Таблица 6.VI.1. Типы с точной шириной
Типы с минимальной шириной
Типы с минимальной шириной гарантируют, что тип имеет размер, равный, как минимум, известному количеству битов. Эти типы существуют всегда. Например, система, которая не поддерживает 8-битовые единицы памяти, могла бы определить int_least_8 как 16-битовый тип. В табл. Б.VI.2 перечислены типы с минимальной шириной, спецификаторы формата и предельные значения.
Таблица 6.VI.2. Типы с минимальной шириной
Самые быстрые типы с минимальной шириной
В отдельной системе некоторые представления целых чисел могут быть быстрее других. Например, int_leastl6_t может быть реализован как short, но система может выполнять арифметические вычисления быстрее, если используется тип int. Таким образом, в заголовочном файле inttypes.h также определены самые быстрые типы для представления, как минимум, определенного количества битов. Эти типы существуют всегда. В некоторых случаях может отсутствовать очевидный выбор для самого быстрого типа, тогда система просто указывает один из возможных вариантов.