Цель C: Unsigned int compare
Итак, я столкнулся с огромной проблемой на работе, потому что в моем коде было что-то вроде этого:
int foo = -1;
NSArray *bar = [[NSArray alloc] initWithObjects:@"1",@"2",@"3", nil];
if (foo > [bar count]){
NSLog(@"Wow, that messed up.");
} else {
NSLog(@"Rock on!");
}
Как вы, наверное, уже знаете, что я размещаю это, вывод:
"Ого, это испортилось".
Из того, что я собираю, цель C преобразует мое отрицательное число в "подписанный" int и, таким образом, убивает мое сравнение.
Я видел другие сообщения об этом, и все они заявили, в чем проблема, но ни один из них не предложил каких-либо простых решений, чтобы получить это сравнение для фактической работы. Кроме того, я в шоке от того, что предупреждений компилятора нет, так как это вызывает серьезные проблемы для меня.
Ответы
Ответ 1
Попробуйте
- (IBAction)btnDoSomething:(id)sender {
int foo = -1;
NSArray *bar = [[NSArray alloc] initWithObjects:@"1",@"2",@"3", nil];
if ( foo > (signed)[bar count] ) {
NSLog(@"Wow, that messed up.");
} else {
NSLog(@"Rock on!");
}
}
В
Если вы сравниваете два разных типа переменных, то он будет неявно преобразовывать тип данных обеих переменных в их более высокий тип.
В этом примере,
переменная foo имеет тип signed int и массив count is unsigned int,
Таким образом, он преобразует тип данных foo в unsigned int
то значение foo станет большим числом, которое меньше, чем число 3 массива.
Таким образом, в этом примере вам нужно свернуть счетчик массива до подписанного int.
Проблемы
Когда ваш счетчик массива превышает максимальный предел подписанного int, то после кастования он округляется назад, как [- (отрицательный) max limit → 0 → + max limit], что является неожиданным результатом.
Решение
- Избегайте литье типов, если вы не уверены в максимальной длине массива.
- Выполните листинг, если вы уверены в ограничении (максимальная длина массива не будет превышать подписанный максимальный предел).
Подробнее об этом подробнее
http://visualcplus.blogspot.in/2006/02/lesson-4-casting-data-types.html
Ответ 2
Проблема
Проблема, с которой вы столкнулись, состоит в том, что, поскольку foo
- целое число со знаком, а -[NSArray count]
возвращает целое число без знака, foo
претерпевает неявное преобразование типа в целое число без знака. Подробнее см. Неявное преобразование типов. Кроме того, здесь больше информации о правилах преобразования типов в C здесь.
Решение
-[NSArray count]
возвращает значение unsigned, потому что массив никогда не может иметь отрицательное число элементов; наименьшее возможное значение равно 0. Сравнение количества массивов с -1 не имеет большого смысла - счет всегда будет больше любого отрицательного числа (несмотря на наличие проблем с знаком).
Итак, правильное решение здесь и способ избежать таких проблем - использовать тип, который соответствует возвращаемому значению -[NSArray count]
, а именно NSUInteger
(U для без знака).