2025-04-12 01:59:20

Целочисленные типы фиксированной ширины.

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

Чтобы облегчить кроссплатформенную переносимость, C99 определил набор целочисленных типов фиксированной ширины (в заголовочном файле stdint.h ), которые гарантированно будут иметь одинаковый размер в любой архитектуре.

Они определены следующим образом:

Название Тип Диапазон значений
std::int8_t 1 байт со знаком от -128 до 127
std::uint8_t 1 байт без знака от 0 до 255
std::int16_t 2 байта со знаком от -32 768 до 32 767
std::uint16_t 2 байта без знака от 0 до 65 535
std::int32_t 4 байт со знаком от -2 147 483 648 до 2 147 483 647
std::uint32_t 4 байта без знака от 0 до 4 294 967 295
std::int64_t 8 байт со знаком от -9 223 372 036 854 775 808 до 9 223 372 036 854 775 807
std::uint64_t 8 байт без знака от 0 до 18 446 744 073 709 551 615

Целочисленные типы фиксированной ширины имеют два недостатка:

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

Во-вторых, если вы используете целочисленный тип фиксированной ширины, на некоторых архитектурах он может быть медленнее, чем более широкий тип. Если вам нужен целочисленный тип для хранения значений от -10 до 20, у вас может возникнуть соблазн использовать std::int8_t. Но ваш процессор мог бы лучше обрабатывать 32-битные целые числа, поэтому вы просто потеряли скорость, сделав ограничение, в котором не было необходимости.

Чтобы устранить указанные выше недостатки язык определяет четыре альтернативных набора целочисленных типов.

Быстрый тип std::int_fast#_t обеспечивает самый быстрый целочисленный тип со знаком с шириной не менее # бит (где # = 8, 16, 32 или 64). Например std::int_fast32_t предоставит вам самый быстрый целочисленный тип со знаком, имеющий как минимум 32 бита.

Наименьший по размеру тип std::int_least#_t предоставляет наименьший по размеру целочисленный тип со знаком с шириной не менее # бит (где # = 8, 16, 32 или 64). Например: std::int_least32_t предоставит вам наименьший целочисленный тип со знаком, имеющий как минимум 32 бита.

Еще два типа являются соответствующими аналогами для типов без знака std::uint_fast#_t и std::uint_least#_t.

Из-за упущения в спецификации большинство компиляторов определяют и обрабатывают std::int8_t и std::uint8_t и соответствующие быстрые и наименьшие по размеру фиксированные типы идентично типам signed char и unsigned char соответственно. Следовательно std::cin и std::cout могут работать иначе, чем вы ожидаете. Ниже приведен пример программы, показывающей это:

#include<cstdint>
#include<iostream>
main( ) {
  int8_t myint{65};
  std::cout << myint;
  return 0;
}

В большинстве систем эта программа будет печатать символ `A` (обрабатывая myint как символ). Однако в некоторых системах может быть напечатано 65, как и ожидалось. Для простоты лучше вообще избегать std::int8_t и std::uint8_t

Лучшие практики работы с целочисленными типами:

Следует использовать тип int всегда, когда максимальное значение переменной не превышает 16 бит. Это покроет подавляющее большинство случаев, с которыми вы, вероятно, столкнетесь.

Если вам нужна переменная гарантированно определенного размера, и вы хотите повысить производительность, используйте std::int_fast#_t.

Если вам нужна переменная, гарантированно имеющая определенный размер, и вы хотите отдать предпочтение экономии памяти над производительностью, используйте std::int_least#_t.

По возможности избегайте следующего:

  • Беззнаковые типы, если у вас нет веской причины.
  • 8-битные целочисленные типы фиксированной ширины.
  • Любые специфичные для компилятора целочисленные типы фиксированной ширины

Тип size_t

Специальный тип данных size_t обычно используется для счетчиков циклов, индексации массивов, хранения размеров, адресной арифметики.

Размер данного типа совпадает с размером указателя. Если для этих целей использовать (unsigned int ) то на 64х разрядной платформе могут быть проблемы с корректной работой приложения, а также теоретическое снижение производительности при индексации.

Комментарии ()