2013-04-23 3 views
10

Так я столкнулся с большой проблемой на работе, потому что у меня было что-то вроде этого в моем коде:Objective C: Неподписанный INT сравнить

int foo = -1; 
    NSArray *bar = [[NSArray alloc] initWithObjects:@"1",@"2",@"3", nil]; 
    if (foo > [bar count]){ 
     NSLog(@"Wow, that's messed up."); 
    } else { 
     NSLog(@"Rock on!"); 
    } 

Как вы, наверное, уже знаете, по мне отправляю это, выход:

«Ого, это испортилось».

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

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

+8

Для этого есть предупреждение для компилятора, но по умолчанию оно не включено. Перейдите на вкладку «Настройки сборки» для своей цели и выполните поиск «Sign Comparison». Включите это предупреждение компилятора. Это может привести к множеству предупреждений. – rmaddy

+2

Возможно, вам захочется пересмотреть то, что должен делать ваш код, поскольку поскольку 'count' является неподписанным, предложение if в основном является мертвой ветвью и может быть удалено. – axiixc

+0

Я повторяю массив, нажимая кнопки «next» или «prev», которые изменяют индексную переменную. Значения массива должны быть циклическими, поэтому, когда индекс меньше 0, он должен быть установлен на последний элемент в массиве. Если индекс больше длины массива, он должен быть равен 0. Таким образом, может быть ситуация, когда индекс равен -1, и я сравниваю его с длиной массива, как показано выше. –

ответ

9

Попробуйте

- (IBAction)btnDoSomething:(id)sender { 
     int foo = -1; 
     NSArray *bar = [[NSArray alloc] initWithObjects:@"1",@"2",@"3", nil]; 
     if (foo > (signed)[bar count]) { 
      NSLog(@"Wow, that's messed up."); 
     } else { 
      NSLog(@"Rock on!"); 
     } 
    } 

Working

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

В этом примере
переменная Foo имеет типа подписанного Int и счетчик массив имеет неподписанных INT,
Так будет преобразовывать тип данных обув в беззнакового Int
того значения обув станет большим числом, которое меньше, чем количество массивов. 3.

Итак, в этом примере вам нужно сдать счетный массив до , подписанный int.


Вопросы

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

Решение

  • типа Избегайте литья, если вы не уверены, максимальная длина массива.
  • Выполняйте литье, если вы уверены в пределе (максимальная длина массива не будет превышать , подписанный int максимальный предел).

Для получения более подробной информации проверить эту
http://visualcplus.blogspot.in/2006/02/lesson-4-casting-data-types.html

+2

'foo' уже подписан. Нет необходимости в трансляции на 'foo'. – rmaddy

+0

@rmaddy вы правы, нет необходимости бросать foo. –

+1

Это тот ответ, который я искал, точно, как заставить это сравнение работать. Благодаря! –

10

Проблема

Проблема вы столкнулись в том, что из-за foo это знаковое целое и -[NSArray count] возвращает целое число без знака , foo претерпевает неявное преобразование типа в целое число без знака. См. Implicit Type Conversion для получения дополнительной информации. Кроме того, есть дополнительная информация о правилах преобразования типов в C here.

Раствор

-[NSArray count] возвращает значение без знака, так как массив не может иметь отрицательное число элементов; наименьшее возможное значение равно 0. Сравнение количества массивов с -1 не имеет большого смысла - счет будет всегда будет больше любого отрицательного числа (несмотря на наличие проблем с знаком).

Таким образом, правильное решение здесь, и способ избежать такого рода проблем, чтобы использовать тип, который соответствует возвращаемому значению -[NSArray count], а именно NSUInteger (и- для без знака).

+1

+1. Это правильное решение. –

+2

Точно, ** при сравнении убедитесь, что оба операнда имеют одинаковый тип **. Это ответ – Krishnabhadra

+1

Нет, это безумие. Как отмечает @Caleb, сравнение длины массива с '-1' не означает * ничего *. Используйте '0'. –

Смежные вопросы