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

StackOverflow https://stackoverflow.com/questions/336

  •  08-06-2019
  •  | 
  •  

Вопрос

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

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

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

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

Это было полезно?

Решение

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

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

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

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

Другие советы

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

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

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

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

Однако я согласен со Сэйнтом в том, что хорошее эмпирическое правило — использовать знак, который C фактически использует по умолчанию, так что вы защищены.

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top