Когда использовать неподписанные значения над подписанными?

Когда целесообразно использовать беззнаковую переменную вместо подписанной? Как насчет forцикла?

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

for (unsigned int i = 0; i < someThing.length(); i++) {  
    SomeThing var = someThing.at(i);  
    // You get the idea.  
}

Я знаю, что у Java нет беззнаковых значений, и это должно было быть осознанным решением со стороны Sun Microsystems .

2.08.2008 03:34:44
Я нашел это полезным: codemines.blogspot.ca/2007/10/…
mk12 23.08.2012 17:31:53
Я думаю, что этот вопрос вполне основан на мнении. Представленный код будет работать в обоих случаях просто отлично, так что вы можете использовать оба. За исключением соображений производительности (пока нет ответа на самом деле о производительности), это просто личный вкус.
Trilarion 9.10.2014 09:13:01
5 ОТВЕТОВ
РЕШЕНИЕ

Я был рад найти хороший разговор на эту тему, так как раньше я об этом не задумывался.

Таким образом, подпись - это хороший общий выбор - даже если вы уверены, что все числа положительные - если вы собираетесь делать арифметику с переменной (как в типичном случае цикла).

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

Лично мне нравится подпись, потому что я не доверяю себе оставаться последовательным и избегать смешивания двух типов (как предостерегает статья).

67
2.08.2008 03:49:21
Позже в этом потоке показано, что unsignedон значительно лучше для обнаружения переполнения на ненадежных входах. К сожалению, предлагаемые «ответы» на загадку не так уж и хороши. Мой вопрос: template<size_t limit> bool range_check_sum( unsigned a, unsigned b ) { return (a < limit) && (b < limit - a); } если у кого-то есть такой же простой и прямой ответ с использованием подписанных типов, я бы хотел его увидеть.
Ben Voigt 13.04.2012 04:18:36

В приведенном выше примере, когда «i» всегда будет положительным, а более высокий диапазон будет полезным, без знака будет полезно. Например, если вы используете операторы «объявлять», такие как:

#declare BIT1 (unsigned int 1)
#declare BIT32 (unsigned int reallybignumber)

Особенно когда эти значения никогда не изменятся.

Однако, если вы ведете бухгалтерскую программу, в которой люди безответственны со своими деньгами и постоянно находятся в минусе, вы наверняка захотите использовать «подписанный».

Я согласен с saint, хотя хорошим правилом является использование подписанного, который на самом деле C по умолчанию, так что вы покрыты.

9
2.08.2008 04:31:54

Компиляторы C и C ++ будут генерировать предупреждение при сравнении типов со знаком и без знака; в вашем примере кода вы не можете сделать вашу переменную цикла неподписанной и заставить компилятор генерировать код без предупреждений (при условии, что указанные предупреждения были включены).

Естественно, вы компилируете с предупреждениями, включенными до конца, верно?

И рассматривали ли вы компиляцию с «обработать предупреждения как ошибки», чтобы сделать еще один шаг вперед?

Недостатком использования чисел со знаком является то, что существует соблазн перегрузить их, так что, например, значения 0-> n являются выбором меню, а -1 означает, что ничего не выбрано, - вместо создания класса, который имеет две переменные, одну для указать, если что-то выбрано и другое, чтобы сохранить, что это за выбор. Прежде чем вы это узнаете, вы проверяете отрицательный результат повсеместно, и компилятор жалуется на то, как вы хотите сравнить выбор меню с количеством вариантов выбора, которые у вас есть - но это опасно, потому что они разных типов , Так что не делай этого.

8
4.08.2008 13:35:41

Я бы подумал, что если ваше экономическое обоснование требует, чтобы отрицательное число было недействительным, вы бы хотели, чтобы ошибка была показана или выдана.

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

8
7.07.2013 15:24:44

size_tчасто хороший выбор для этого, или size_typeесли вы используете класс STL.

6
23.08.2012 17:27:58
Только когда вы имеете дело с размером чего-то в байтах.
mk12 23.08.2012 17:27:41
@ mk12 Контейнеры стандартной библиотеки предоставляют size_typeчлену счетчик элементов, а не только байтов. Его следует использовать вместо того, std::size_tгде оно доступно, но неточно предполагать, что все, что начинается с, size_tможет означать только байты.
underscore_d 24.06.2019 19:05:55