Выбор наиболее подходящего целочисленного размера / диапазона для использования для переменных - PullRequest
6 голосов
/ 14 октября 2010

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 бит.
Как устройство, на котором будет работать код, влияет на выбор? т.е. рабочий стол, телефон, консоль.
Как выбор относится к производительности и оптимизации?

У меня простой вопрос: как выбрать целое число для использования?

Ответы [ 4 ]

4 голосов
/ 14 октября 2010

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

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

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

3 голосов
/ 14 октября 2010

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

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

  • Всегда выбирайте правильную подпись для значений, которые вы будете хранить.
  • Для подсчета объектов, индексов, длин строк / данных в памяти и т. Д. Используйте size_t.
  • Для данных с определенным диапазоном значений, которые необходимо хранить и в которых вам никогда не потребуется хранить значения, выходящие за пределы диапазона, используйте один из целочисленных типов фиксированного размера из stdint.h (uint8_t, uint16_t, uint32_t и т. Д.). Распространенными примерами такого рода потребностей, которые приходят на ум, являются значения пикселей, аудиосэмплы и символы Unicode (обычно 8, 16 и 32-битные соответственно).
  • В противном случае int или unsigned, вероятно, является правильным типом для использования.
1 голос
/ 14 октября 2010

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

1 голос
/ 14 октября 2010

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

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

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

...