NSUInteger vs NSInteger, int vs unsigned и аналогичные случаи


У кого-нибудь есть опыт, чтобы объяснить, когда использовать NSUInteger и когда использовать NSInteger?

Я видел методы Cocoa, возвращающие NSInteger даже в тех случаях, когда возвращаемое значение всегда будет без знака.

Какова основная причина? NSInteger или int строго ограничены, если мы хотим представить отрицательное значение?

Из NSObjCRuntime.h:

#if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64
typedef long NSInteger;
typedef unsigned long NSUInteger;
#else
typedef int NSInteger;
typedef unsigned int NSUInteger;
#endif
4 28

4 ответа:

Вы также должны знать правила преобразования целых чисел при работе с NSUInteger против NSInteger:

Следующий фрагмент, например, возвращает 0 (false), хотя вы ожидаете, что он будет печатать 1 (true):

NSInteger si = -1;
NSUInteger ui = 1;
printf("%d\n", si < ui);

Причина в том, что переменная [si] неявно преобразуется в unsigned int!

СмотритеСайт CERT по безопасному кодированию для углубленного обсуждения этих "проблем" и способов их решения.

По умолчанию целое число считается подписанным. Другими словами, компилятор предполагает, что целочисленная переменная будет вызвана для хранения отрицательного или положительного числа. Это ограничивает диапазон, который может быть достигнут в любом направлении. Например, 32-разрядный int имеет диапазон 4 294 967 295. На практике, поскольку значение может быть положительным или отрицательным, диапазон на самом деле составляет от -2,147,483,648 до +2,147,483,647. Если мы знаем, что переменная никогда не будет вызвана для хранения отрицательного значения значение, мы можем объявить его как беззнаковое, тем самым расширяя (положительный) диапазон от 0 до +4,294,967,295. Поэтому я бы сказал, что это нормально использовать NSInteger, когда вы знаете, что у вас есть ограниченный диапазон выходных данных. Я лично использую NSUInteger, если мне нужно вернуть действительно большие положительные только числа

Если ваш метод имеет достаточно ограниченный диапазон вывода, вы можете также использовать NSInteger, так как это проще для ввода. Как вы говорите, если вам нужно вернуть отрицательные числа, NSInteger - единственная игра в городе; я бы использовал NSUInteger только в том случае, если бы мне нужно было вернуть действительно большие числа по какой-то причине.

Я не знаю о какао конкретно, но обычно единственным недостатком знаковых целых чисел является то, что они обычно имеют половину максимального значения как unsigned int. Например, около 2 миллиардов вместо 4 миллиардов для 32-битных систем. Как правило, это не большая разница, так как если вы имеете дело со значениями, близкими к 2 миллиардам, вы, вероятно, будете так же беспокоиться о максимуме в 4 миллиарда в том же случае, так как он все еще довольно близок к переполнению с простым умножением на 2 или 3.

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

Unsigned может быть предпочтительнее, если вы хотите применять только положительные значения.