Що таке &&& робота в C


195
#include <stdio.h>

volatile int i;

int main()
{
    int c;

    for (i = 0; i < 3; i++) 
    {
         c = i &&& i;
         printf("%d\n", c);
    }

    return 0;
}

Вихід з вищезгаданої програми, складений за допомогою, gccє

0
1
1

За допомогою параметра -Wallабо або -Waddressнадсилає gccпопередження:

warning: the address of i will always evaluate as true [-Waddress]

Як cоцінюється вищевказана програма?


42
Я вірю, що це i && (&i)? Цікаво, що я не можу знайти дублюючу публікацію на SO.
безславний

42
while (i &&& i <-- j) {}.
kennytm


8
Не дублікат, але з подібним питанням, і це гарне посилання
Натан Купер

Відповіді:


272

Це так c = i && (&i);, що друга частина є зайвою, оскільки &iніколи її не оцінюватимуть false.

Для визначеного користувачем типу, де ви можете насправді перевантажувати одиничні operator &, це може бути інакше, але це все ще дуже погана ідея .

Якщо увімкнути попередження , ви отримаєте щось на зразок:

попередження: адреса "я" завжди буде оцінюватися як "справжня"


1
Чому б і ні c = i & (&&i);:; Де iякась етикетка?
anishsane

4
@anishsane iвизначається як intі немає міток у питанні. Крім того, максимальний
жарт

5
@anishsane: І &&оператор, щоб взяти адресу мітки, все одно є нестандартним розширенням gcc. Але навіть якби це було стандартно, правило максимального збігу не дозволило б розібратися таким чином (якщо ви не вставите пробіл).
Кіт Томпсон

Насправді, &iможна оцінити false. Його іноді використовують для дефолтів. Приклад: void fn(type& x = *reinterpret_cast<type*>(NULL)); Яке значення &xв, fnякщо fnвикликається без параметрів? Це 0 aka false. Однак, використовуючи його так, як описано, це завжди буде правдою, якщо i == 0, і якби хтось використовував його, як я описав, це було б c = &i && i.
Адріан

@LuchianGrigore: як так?
Адріан

118

У &&&C. немає жодного оператора чи маркера. Але &&(логічні "і") і &(одинарна адреса або порозрядне "і") оператори існують.

За правилом максимального манкування це:

c = i &&& i;

еквівалентно цьому:

c = i && & i;

Він встановлює c1, якщо обидва iі &iє істинними, і 0, якщо будь-який з них неправдивий.

Для int будь-яке ненульове значення є істинним. Для вказівника будь-яке ненулеве значення є істинним (а адреса об'єкта завжди несуттєва). Так:

Він встановлюється cна 1, якщо iвін не дорівнює нулю, або на значення, 0якщо iдорівнює нулю.

Звідси випливає, що &&&тут використовується просто для навмисного заблудження. Призначенням може бути також будь-яке з наступного:

c = i && 1;
c = !!i;
c = (bool)i;          // C++ or C with <stdbool.h>
c = i ? 1 : 0;        /* C */
c = i ? true : false; // C++
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.