Выбор наиболее подходящего целочисленного размера/диапазона для переменных

stdint.h в C99 предоставляет множество вариантов целочисленных размеров, типов и диапазонов - так много, что я не знаю, какие выбрать!

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

Например, структура изображения может содержать следующие члены:

struct image {
    integer width, height; /* pixel dimensions of the image */
    integer bits_per_pixel;
    ...
};

Если width и height никогда не превысят SHRT_MAX, следует ли использовать short или придерживаться int? Изображение не может иметь отрицательную ширину или высоту, поэтому используйте беззнаковый тип? Возможно, (u)int_least16_t правильный выбор? Что-то другое?

Если bits_per_pixel никогда не превысит значение 64, используйте char, unsigned char, uint8_t, int или что-то еще?

Что бы вы использовали в этом примере и почему?

Как архитектура ЦП, на которой будет выполняться код, влияет на выбор? например, PPC или x86, 32 или 64 бит.
Как устройство, на котором будет выполняться код, влияет на выбор? например, настольный компьютер, телефон, консоль.
Как выбор связан с производительностью и оптимизацией?

Мой вопрос простыми словами: как вы выбираете, какое целое число использовать?


person x-x    schedule 14.10.2010    source источник


Ответы (4)


Я бы сказал: не беспокойтесь об этом, часто это форма преждевременной оптимизации. Но мои эмпирические правила таковы:

  • По возможности используйте простой int. Это должен быть естественный размер слова машины.
  • Используйте типы unsigned, когда вам нужно четко определенное целочисленное переполнение.
  • Используйте тип (u)intX_t, когда вам нужно представление с дополнением до двух.
  • Используйте unsigned char для больших массивов со значениями <= UCHAR_MAX.

Имейте в виду, что многие типы в <stdint.h> являются необязательными, поэтому вы не можете зависеть от их существования. POSIX делает это немного лучше.

person schot    schedule 14.10.2010

В вашем примере я бы просто использовал int или (возможно, лучше) unsigned для всех трех полей. Нет смысла использовать меньшие типы, кроме как в массиве, который будет содержать тысячи или миллионы элементов; это просто накладывает искусственные ограничения.

Чтобы ответить на более общий вопрос, вот несколько рекомендаций, которым я следую:

  • Всегда выбирайте правильную подпись для значений, которые вы будете хранить.
  • Для подсчета объектов, индексов, длин строк/данных в памяти и т. д. используйте size_t.
  • Для данных, которые имеют определенный диапазон значений, которые вам нужно хранить, и где вам никогда не потребуется хранить значения за пределами этого диапазона, используйте один из целочисленных типов фиксированного размера из stdint.h (uint8_t, uint16_t, uint32_t, так далее.). Типичными примерами такого рода потребностей, которые приходят на ум, являются значения пикселей, аудиосэмплы и символы Unicode (обычно 8, 16 и 32 бита соответственно).
  • В противном случае, int или unsigned, вероятно, правильный тип для использования.
person R.. GitHub STOP HELPING ICE    schedule 14.10.2010

Нет жестких и быстрых правил.

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

Если вы не сталкиваетесь с проблемами производительности для своей конкретной задачи, я бы определенно склонялся к «слишком большому». Хотя использовать целое число для бит/пиксель довольно глупо, вероятно, это ничему не повредит в большей схеме вещей.

person nsanders    schedule 14.10.2010

Если ваше приложение действительно интенсивно использует память, не беспокойтесь о размерах и используйте int. Использование short или char может привести к незначительным ошибкам, которые позже могут вызвать проблемы. Кроме того, использование char или short не даст вам дополнительных циклов процессора.

person patentfox    schedule 14.10.2010