Подтвердить что ты не робот

Что значит!! означает синтаксис objective-c?

Я нашел код, похожий на следующий:

BOOL hasValue_:1;

- (BOOL) hasValue {
    return !!hasValue_;
}

- (void) setHasValue:(BOOL) value {
    hasValue_ = !!value;
}

Мне интересно, почему нужны двойные восклицательные знаки? Разве мы не передаем BOOL методу и не возвращаем BOOL? Является ли BOOL действительно typedef для int?

Спасибо!

ИЗМЕНИТЬ
Спасибо за все ответы. Я понимаю, что используя!! с другими типами данных эффективно выполняет некоторое приведение к логическому результату. Однако в приведенном выше примере я строго работаю с BOOL уже.

ИЗМЕНИТЬ
Если я уже работаю с BOOL, зачем нужно нормализовать его на 0 для false и 1 для true? Разве BOOL не гарантирует, что она ложна для 0 и истинна для всего остального?

4b9b3361

Ответ 1

Мне интересно, почему нужны двойные восклицательные знаки?

BOOL - это signed char или char, представляющий собой булевский тип через typedef. Он будет счастливо представлять любое целое число в диапазоне [SCHAR_MIN...SCHAR_MAX]. Двойной восклицательный знак применяет логическую операцию NOT дважды, что эффективно преобразует исходное значение в int из 0 или 1, сужая значение до диапазона логических значений.

Но есть твист: BOOL hasValue_:1; объявляет однобитовое представление битового поля. Он может представлять два значения. return !!hasValue_; не требуется. Тем не менее, необходимо правильно сузить при переходе от signed char (BOOL) к одному биту.

Разве мы не передаем BOOL методу и не возвращаем BOOL?

Неа. Это a signed char. !!value уменьшает входные значения до YES или NO.

Если я уже работаю с BOOL, зачем нужно нормализовать его на 0 для false и 1 для true?

Разве BOOL не гарантирует, что оно ложно для 0 и true для всего остального?

BOOL является signed char. A typedef of signed char не гарантирует эту гарантию.

C99 (который был доступен для вас в течение многих лет при ориентации на osx или ios), имеет более полезное представление типа boolean (BOOL). К сожалению, BOOL по-прежнему используется в objc по историческим причинам. Лично я использую BOOL только при необходимости (например, переопределение).

Ответ 2

Я не уверен на 100% объективности C, но на других языках это два булевых оператора рядом друг с другом. Он обычно используется для обеспечения преобразования фальшивых или trusy-операторов в правильные логические значения (например, true или false). Поскольку цель C получена из C, есть хороший шанс, что это также то, для чего она использовалась.

Ответ 3

Рассматривая этот вопрос, BOOL является typedef для signed char. Это означает, что он может иметь значения, отличные от 0 или 1 (во всех современных системах, с которыми я знаком, он может иметь значения от -128 до 127). Это не должно, но я не хотел бы рассчитывать на BOOL, всегда имеющий значения 0 или 1.

Следовательно, желательно иметь способ нормализации его к 0 или 1. В C и производных языках, с которыми я знаком, ! - это оператор not, который принимает значение и возвращает либо 1, если значение обрабатывается как false (в C, который был бы числом 0 или 0.0 или константой нулевого указателя для типа указателя) и 0 в противном случае. !! применяется только !, применяемое дважды, что дает 0 для первоначально ложного значения и 1 для первоначально истинного значения.

Ответ 4

Двойные восклицательные знаки - это способ передать целое число в BOOL, где 1 (и любое другое значение!= 0) истинно, а 0 - false. Кроме того, то, что вы пишете, это C, а не objective-c. Ваш код будет работать и в среде С++, так как он также является производным от c.

Ответ 5

Оператор ! применяется дважды. Оператор отрицает его логический аргумент.

Итак, какой смысл применять его дважды, разве вы не вернетесь туда, где вы начали? Не обязательно, поскольку тип аргумента может быть любого типа. Это означает, что вы могли бы иметь что-то вроде целого i и проверить, не отличен ли он от !!i. Кроме того, это часто используется для проверки того, является ли указатель не равным NULL, например:

bool doTrace = !!getenv("MY_TEST_VAR");

Ответ 6

... Некоторые из его диалектов, такие как C99 и Objective-C, предоставляют стандартные определения булевого типа в качестве синонима int и макросов для "false" и "true" как 0 и 1. соответственно.

Википедия - тип данных Boolean

Я думаю, что двойное отрицание гарантирует, что значение "true" равно 1 (возможно, использовать его в арифметических операциях).