Я использую целые числа без знака везде, и я не уверен, должен ли я. Это может быть от столбцов идентификаторов первичного ключа базы данных до счетчиков и т. Д. Если число никогда не должно быть отрицательным, тогда я всегда буду использовать беззнаковое целое.
Однако я замечаю из кода другого, что никто другой, кажется, не делает этого. Есть ли что-то важное, что я упускаю из виду?
Изменить: После этого вопроса я также заметил, что в C возвращение отрицательных значений для ошибок является обычным явлением, а не генерирует исключения, как в C ++.
c++
c
programming-practices
wting
источник
источник
for(unsigned int n = 10; n >= 0; n --)
(петли бесконечно)Ответы:
Когда в расчетах участвуют как подписанные, так и неподписанные типы, а также разные размеры, правила продвижения типов могут быть сложными и приводить к неожиданному поведению .
Я считаю, что это основная причина, по которой Java опускает типы unsigned int.
источник
int
не представляют такой трудности (поскольку любые вычисления будут способствоватьint
); Я не могу сказать ничего хорошего об отсутствии типа без знака.Я думаю, что у Майкла есть верное замечание, но IMO причина, по которой все постоянно используют int (особенно in
for (int i = 0; i < max, i++
), заключается в том, что мы изучили его таким образом. Когда каждый пример в « как научиться программировать » книга используетint
вfor
цикле, очень немногие когда - либо вопрос такой практики.Другая причина в том, что
int
она на 25% корочеuint
, а мы все ленивые ... ;-)источник
++
при увеличении, несмотря на тот факт, что его конкретное поведение редко требуется и может даже привести к бессмысленному перетеканию копий, если индекс цикла является итератором или другим неосновным типом (или компилятор действительно плотный) ,Кодирование информации о диапазоне в типы - это хорошо. Он обеспечивает использование разумных чисел во время компиляции.
Кажется, что во многих архитектурах есть специальные инструкции для работы с
int
->float
преобразованиями. Преобразование изunsigned
может быть медленнее (чуть-чуть) .источник
Смешивание подписанных и неподписанных типов может привести к боли. И вы не можете использовать все типы без знака, потому что вы столкнетесь с вещами, которые либо имеют допустимый диапазон, который включает отрицательные числа, либо нуждаются в значении, указывающем на ошибку, и -1 является наиболее естественным. Таким образом, в результате многие программисты используют целые типы со знаком.
источник
Для меня типы много о коммуникации. Используя явно беззнаковое целое, вы говорите мне, что подписанные значения не являются допустимыми значениями. Это позволяет мне добавить некоторую информацию при чтении вашего кода в дополнение к имени переменной. В идеале я неанонимный тип сказал бы мне больше, но он дает мне больше информации, чем если бы вы использовали целые числа везде.
К сожалению, не все очень хорошо понимают, о чем говорит их код, и это, вероятно, причина, по которой вы видите целые числа везде, даже если значения по крайней мере без знака.
источник
Я использую
unsigned int
в C ++ для индексов массивов, в основном, и для любого счетчика, который начинается с 0. Я думаю, что было бы хорошо сказать явно: «эта переменная не может быть отрицательной».источник
Вам следует позаботиться об этом, когда вы имеете дело с целым числом, которое на самом деле может приближаться или превышать пределы подписанного типа int Поскольку положительный максимум 32-разрядного целого числа составляет 2 147 483 647, вам следует использовать целое число без знака, если вы знаете, что оно a) никогда не будет отрицательным и b) может достигать 2 147 483 648. В большинстве случаев, включая ключи базы данных и счетчики, я никогда даже не подойду к этим видам чисел, поэтому я не беспокоюсь о том, волнуюсь ли, используется ли знаковый бит для числового значения или для обозначения знака.
Я бы сказал: используйте int, если вы не знаете, что вам нужен неподписанный int.
источник
Это компромисс между простотой и надежностью. Чем больше ошибок можно обнаружить во время компиляции, тем надежнее программное обеспечение. Разные люди и организации находятся в разных точках этого спектра.
Если вы когда-нибудь выполняете какое-либо высоконадежное программирование в Ada, вы даже используете различные типы переменных, таких как расстояние в футах и расстояние в метрах, и компилятор помечает его, если вы случайно назначаете одно другому. Это идеально подходит для программирования управляемой ракеты, но излишне (каламбур), если вы проверяете веб-форму. В любом случае нет ничего плохого, если это соответствует требованиям.
источник
Я склонен согласиться с доводами Джоэла Этертона, но прихожу к противоположному выводу. На мой взгляд, даже если вы знаете, что числа вряд ли когда-либо приблизятся к пределам типа со знаком , если вы знаете, что отрицательных чисел не произойдет, то есть очень мало причин использовать вариант типа со знаком.
По той же причине, по которой я в некоторых выбранных случаях использовал
BIGINT
(64-разрядное целое), а неINTEGER
(32-разрядное целое) в таблицах SQL Server. Вероятность того, что данные достигнут 32-битного предела в течение любого разумного промежутка времени, ничтожна, но если это произойдет, последствия в некоторых ситуациях могут быть весьма разрушительными. Просто убедитесь, что вы правильно сопоставляете типы между языками, иначе у вас будет странная странность ...Тем не менее, для некоторых вещей, таких как значения первичного ключа базы данных, подписанные или неподписанные, действительно не имеет значения, потому что, если вы вручную не исправляете поврежденные данные или что-то в этом роде, вы никогда не будете иметь дело со значением напрямую; это идентификатор, не более того. В этих случаях последовательность, вероятно, важнее, чем точный выбор подписи. В противном случае вы получите столбцы с внешним ключом, которые будут подписаны, и другие, которые не будут подписаны, без какого-либо очевидного паттерна - или снова эта интересная странность.
источник
Я бы порекомендовал, чтобы за пределами ограниченного пространства хранения данных и обмена данными, как правило, использовались подписанные типы. В большинстве случаев, когда 32-разрядное целое число со знаком было бы слишком маленьким, но 32-разрядного значения без знака было бы достаточно для сегодняшнего дня, это не займет много времени, прежде чем 32-разрядное значение без знака также не станет достаточно большим.
Основное время, когда следует использовать типы без знака, - это когда кто-либо собирает несколько значений в большее (например, преобразует четыре байта в 32-разрядное число) или разбивает большие значения на меньшие (например, сохраняет 32-разрядное число в виде четырех байтов). ) или когда у человека есть количество, которое, как ожидается, будет периодически «переворачиваться», и с ним нужно иметь дело (подумайте о счетчике коммунальных услуг; у большинства из них достаточно цифр, чтобы они не могли перевернуться между показаниями) если они читаются три раза в год, но недостаточно, чтобы гарантировать, что они не перевернутся в течение срока службы счетчика). Беззнаковые типы часто имеют достаточно «странностей», чтобы их можно было использовать только в тех случаях, когда необходима их семантика.
источник
size_t
не подписано иptrdiff_t
подписано.Я использую целые числа без знака, чтобы сделать мой код и его цель более понятными. Одна вещь, которую я делаю, чтобы защититься от неожиданных неявных преобразований при выполнении арифметики как со знаком, так и без знака, - это использовать беззнаковое короткое (обычно 2 байта) для моих беззнаковых переменных. Это эффективно по нескольким причинам:
Общий принцип заключается в том, что тип переменных без знака должен иметь более низкий ранг, чем тип переменных со знаком, чтобы обеспечить переход к типу со знаком. Тогда у вас не будет неожиданного поведения переполнения. Очевидно, что вы не можете гарантировать это все время, но (чаще всего) это возможно.
Например, недавно у меня был цикл for что-то вроде этого:
Литерал '2' имеет тип int. Если бы я был unsigned int вместо unsigned short, то в подвыражении (i-2) 2 было бы переведено в unsigned int (поскольку unsigned int имеет более высокий приоритет, чем sign int). Если i = 0, то подвыражение равно (0u-2u) = некоторое массовое значение из-за переполнения. Та же идея с i = 1. Однако, так как я - беззнаковое короткое слово, оно получает тот же тип, что и литерал '2', который подписан как int, и все работает нормально.
Для дополнительной безопасности: в редком случае, когда архитектура, которую вы реализуете, приводит к тому, что значение int равно 2 байтам, это может привести к тому, что оба операнда в арифметическом выражении будут переведены в unsigned int, если неподписанная короткая переменная не подходит в подписанный 2-байтовый int, последний из которых имеет максимальное значение 32 767 <65 535. (См. Https://stackoverflow.com/questions/17832815/c-implicit-conversion-signed-unsigned для получения дополнительной информации). Чтобы избежать этого, вы можете просто добавить static_assert в вашу программу следующим образом:
и он не скомпилируется на архитектурах, где int составляет 2 байта.
источник