NSUInteger vs NSInteger, int vs без знака и подобные случаи

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

Я видел, как методы Какао возвращают 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 ответа

Решение

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

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

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

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

См . Сайт безопасного кодирования 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 если бы мне нужно было вернуть действительно большие числа по какой-то причине.

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

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

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

Другие вопросы по тегам