Цель 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 для без знака).