2016-02-28 7 views
8

Мой друг в шутку задал мне этот вопрос. Предполагалось, что это будет «само собой разумеющееся», но потом я подумал об этом некоторое время и начал придумывать какие-то умные «решения почти».Когда есть (x ||! X) false?

Первая попытка:

Если C всегда поддерживает квантовые вычисления могут быть ответом на это. Q-бит может быть во многих состояниях одновременно, поэтому он может быть ложным и истинным, и это условие возвращает (BOOL)0.5 aka «Да/нет/возможно-так» - но как только вы заметите переменную, вся вещь рухнет и станет недействительной еще раз.

Вторая попытка:

Если X может быть как-то определяются как случайный двоичный генератор и вы приводите его к BOOL вы можете получить ложную часть времени. Я не уверен, что вы можете сделать это, хотя в C, если вы не используете CLANG. #define x (BOOL)!!(rand()%2)



язык мы обсуждали это в это C, но я также интересно, если кто может найти какие-либо решения в любого языка.

+2

Ответ: Неопределенное поведение. – SLaks

+9

Вот вопрос, который Гамлет задавал сотни лет назад: 'bb || ! Bb'. – nsilent22

+0

@ nsilent22 Я смеялся немного hardhard –

ответ

16

Когда x является летучим (volatile int x) и модифицируют с помощью наружной резьбой/устройства, выражение может быть ложным .

+0

Интересное решение! Интересно, есть ли способ сделать это без непосредственной модификации переменной в другой точке кода –

+0

Как я уже указывал, если «x» отображается на внешнюю измененную ячейку памяти/регистр, это может произойти «спонтанно» – Amit

+0

Oh ты прав! Это довольно гениально! Хотя это не всегда * всегда * ложно, hmm –

4

Макросы действительно обманывают здесь, но вам не нужны какие-либо действия с булевыми типами или специальными компиляторами. Далее, насколько я знаю, является законным стандартом C.

#include <stdio.h> 
int f(void) { 
    static int y = 0; 
    if (y == 0) { 
    y = 1; 
    return 0; 
    } else { 
    return 1; 
    } 
} 

#define x f() 

int main(void) { 
    if (x || !x) { 
    puts("It was true"); 
    } else { 
    puts("It was false"); 
    } 
    return 0; 
} 

Или еще более лаконично:

int y = 0; 
#define x y++ 

(Для тех, кто беспокоится о неопределенном поведении, обратите внимание, что точка последовательности между левым и правая сторона ||)

+0

Я работал над чем-то подобным, используя CLANG в Obj-C. Я получил это далеко '#define x (BOOL) [[NSUserDefaults standardUserDefaults] integerForKey: @" x "]; [[NSUserDefaults standardUserDefaults] setInteger: (int)! (BOOL) [[NSUserDefaults standardUserDefaults] integerForKey: @" x "] forKey: @ "x"]; [[NSUserDefaults standardUserDefaults] synchronize]; 'перед тем, как понять, что я не могу иметь функции внутри условных объектов в объекте-c (насколько я знаю) –

+0

@AlbertRenshaw: У меня нет понятия, что это делает, но кажется waaaaaaaaay сложнее. –

9

Это немного трюк, но следующее решение также работает:.

#define x 1 ? 0 : 1 
(x || !x) 

Причина в приоритете оператора. После предварительной обработки (x || !x) решает следующие (скобки добавлены, чтобы показать преимущество):

(1 ? 0 : (1 || !1) ? 0 : 1) 
+1

Это замечательно - fav ответ –

+2

Вы можете сделать это еще проще: '#define x 1 && 0' или даже' #define x 1,0' – Joni

+0

@Joni Это отличный ответ! Пожалуйста, опубликуйте его: D –

4

Еще более простой макрос:

#define x 0&0 

(x || !x) расширение дает (0 & 0 || !0 & 0), который всегда ложно.

Аналогично:

#define x 0*0 
#define x 1*0 // for binary buffs 
#define x 4&2 // for HHGG fans. 

Я не мог найти 2 письмо макрос :(

+0

В этом случае любой макрос «... & 0» будет работать – vittore

+1

@vittore: действительно, '1 & 0' будет работать и имеет меньше пикселей, а' 4 & 2' более застенчиво. – chqrlie

2

а если х является тип charecter (т.е. не INT или BOOL), то некоторый язык как JS, PHP и т.д. может привести к выражение, как ложное.

, что означает, что в случае ошибки литья типа

для

char x = "string";

(х ||! Х) = False (0 или NaN)

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

self cast eg.g. char a = "10"; int b = (int) a;

новый товар ver. языка также включают тестовую литьевую смесь.

1

Пробовал в JS:

вар я = 0

я ++ || ! (i ++)

Примечание: это решение работает только при i = 0

+0

, пожалуйста, нажмите кнопку образца кода, которая может быть показана как {}, затем вставьте код. –

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