Что значит !!значит в синтаксисе цель-c? - PullRequest
17 голосов
/ 08 апреля 2011

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

BOOL hasValue_:1;

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

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

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

Спасибо!

EDIT
Спасибо за все ответы до сих пор.Я понимаю, что с помощью !!с другими типами данных эффективно выполняет некоторое приведение типов к логическому результату.Однако в приведенном выше примере я уже строго работаю с BOOL.

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

Ответы [ 6 ]

13 голосов
/ 27 мая 2012

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

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

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

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

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

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

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

BOOL является signed char. typedef из signed char не дает этой гарантии.

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

4 голосов
/ 08 апреля 2011

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

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

4 голосов
/ 08 апреля 2011

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

3 голосов
/ 08 апреля 2011

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

2 голосов
/ 08 апреля 2011

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

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

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

2 голосов
/ 08 апреля 2011

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

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

bool doTrace = !!getenv("MY_TEST_VAR");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...