Подтвердить что ты не робот

Используя uint vs int

Я некоторое время наблюдал, что программисты на С# обычно используют int везде и редко прибегают к uint. Но я никогда не обнаружил удовлетворительного ответа на вопрос о том, почему.

Если интероперабельность - это ваша цель, uint не должен появляться в общедоступных API, потому что не все языки CLI поддерживают целые числа без знака. Но это не объясняет, почему int настолько распространен, даже во внутренних классах. Я подозреваю, что это причина, по которой uint используется экономно в BCL.

В С++, если у вас есть целое число, для которого отрицательные значения не имеют смысла, вы выбираете целое число без знака.

Это явно означает, что отрицательные числа не допускаются или ожидаются, и компилятор проведет вас для проверки. Я также подозреваю в случае индексов массива, что JIT может легко отбросить проверку нижних границ.

Однако, при смешивании типов int и unit, потребуется дополнительная осторожность и отливки.

Следует ли использовать uint больше? Почему?

4b9b3361

Ответ 1

Ваше наблюдение за тем, почему uint не используется в BCL, является основной причиной, я подозреваю.

UInt32 не является совместимым с CLS, что означает, что он полностью неприемлем для использования в публичных API. Если вы собираетесь использовать uint в своем частном API, это будет означать выполнение преобразований для других типов - и, как правило, проще и безопаснее просто сохранить тип один и тот же.

Я также подозреваю, что это не так часто встречается в разработке С#, даже когда С# является единственным используемым языком, в первую очередь потому, что он не распространен в BCL. Разработчики, в общем, пытаются (к счастью) имитировать стиль структуры, на которой они строятся - в случае с С#, это означает, что вы пытаетесь сделать ваши API, общедоступными и внутренними, как можно более похожими на .NET Framework BCL. Это будет означать использование uint экономно.

Ответ 2

int короче, чем uint.

Ответ 3

Обычно int будет достаточно. Если вы можете выполнить все следующие условия, вы можете использовать uint:

  • Это не для общедоступного API (поскольку uint не соответствует CLS).
  • Вам не нужны отрицательные числа.
  • Вам может потребоваться дополнительный диапазон.
  • Вы не используете его в сравнении с < 0, поскольку это никогда не true.
  • Вы не используете его в сравнении с >= 0, поскольку это никогда не false.

Последнее требование часто забывается и вводит ошибки:

static void Main(string[] args)
{
    if (args.Length == 0) return;
    uint last = (uint)(args.Length - 1);

    // This will eventually throw an IndexOutOfRangeException:
    for (uint i = last; i >= 0; i--)
    {
        Console.WriteLine(args[i]);
    }
}

Ответ 4

1) Плохая привычка. Шутки в сторону. Даже в C/С++.

Подумайте об общем шаблоне for:

for( int i=0; i<3; i++ )
    foo(i);

Там нет никакой причины использовать целое число. У вас никогда не будет отрицательных значений. Но почти каждый будет делать простой цикл таким образом, даже если он содержит (по крайней мере) две другие ошибки "стиля".

2) int воспринимается как собственный тип машины.

Ответ 5

Я предпочитаю uint до int, если отрицательное число действительно находится в диапазоне допустимых значений. В частности, принятие параметра int, но бросание ArgumentException, если число меньше нуля, просто глупо - используйте uint!

Я согласен, что uint недостаточно используется, и я призываю всех остальных использовать его больше.

Ответ 6

Я программирую на уровне приложений более низкого уровня, где ints редко превышает 100, поэтому отрицательные значения не являются проблемой (например, для типа я < myname.length()), это просто старая привычка C - и более короткая для ввода как уже упоминалось выше. Однако в некоторых случаях при взаимодействии с оборудованием, где я имею дело с флагами событий с устройств, uint важен в случаях, когда флаг может использовать самый старший бит.

Честно говоря, для 99,9% моей работы я мог легко использовать ushort, но int, вы знаете, звучит намного лучше, чем ushort.

Ответ 7

Я сделал оболочку Direct3D 10 в С# и мне нужно использовать uint, если я хочу создать очень большие вершинные буферы. Большие буферы в видеокарте не могут быть представлены с подписанным int.

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

Ответ 8

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

C и С++, однако, имеют глубокие корни в старых системах и встроенных системах, где память разрежена, поэтому программисты используют для тщательного анализа того, какой тип данных использовать. Программисты С# ленивы, и, поскольку в целом достаточно ресурсов, никто не оптимизирует использование памяти (в общем, не всегда, конечно). Событие, если байт будет достаточным, много программистов на С#, включая меня, просто используют int для простоты. Более того, многие функции API принимают ints, поэтому он предотвращает кастинг.

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

Наконец, выбор целого числа более математически корректен. Unsigned ints не существуют в математике (только натуральные числа). И поскольку большинство программистов имеют математический фон, использование целого числа является более естественным.

Ответ 9

Я думаю, что большая часть причины заключается в том, что, когда C впервые выработал большинство примеров, используемых int для краткости. Мы радовались тому, что нам не приходилось писать integer, как мы это делали с Fortran и Pascal, и в те дни мы обычно использовали их для мирских вещей, таких как индексы массивов и счетчики циклов. Целочисленные целые числа были специальными случаями для больших чисел, которые нуждались в последнем дополнительном бите. Я думаю, что это естественная прогрессия, которую привычки C продолжали в С# и другие новые языки, такие как Python.

Ответ 10

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

Другие языки (например, C) рассматривают N-разрядные неподписанные типы как группу, которая обертывается по модулю 2 ^ N. Обратите внимание, что вычитание N из члена такой группы не представляет собой числовое вычитание, а скорее дает член группы, который при добавлении N к нему даст исходный код. Возможно, некоторые операции, связанные с смесями подписанных и неподписанных значений, на самом деле не имеют смысла и, возможно, должны быть запрещены, но обычно будет работать даже код, который неаккуратно со своими спецификациями таких вещей, как числовые литералы, и был написан код, и неподписанные типы и, несмотря на то, что они неаккуратные, работают, что спецификация не скоро изменится в ближайшее время.

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

Ответ 11

Я знаю, что это, вероятно, старая нить, но я хотел бы дать некоторое разъяснение.

Давайте возьмем int8, вы можете хранить от -128 до 127 и использовать 1 байт, что составляет в общей сложности 127 положительных чисел.
Когда вы используете int8, один из битов используется для отрицательных чисел -128.
Когда вы используете Uint8, вы даете отрицательные числа положительному, так что это позволяет использовать 255 положительных чисел с одинаковым объемом хранения 1 байт.
Единственный откат - вы потеряли способность использовать отрицательные значения.
Другой проблемой является не все языки программирования и базы данных. Единственная причина, по которой вы бы использовали это, по моему мнению, - это то, когда вам нужно быть эффективным в программировании игр, и вам нужно хранить большие неотрицательные числа. Вот почему не многие программы используют это.

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

Надеюсь, это поможет кому-то.