2016-07-07 4 views
-5

У меня есть цикл while, который проходит через строку, пока не достигнет нескольких символов.C# логическое сравнение с || или &&

while (json[z-2] != 's' && json[z] != ':') 
{ z++; } 

Я думал && средства и, и это должно было в цикле, пока он не достиг места в строке, где s и : символы были 1 символ расставленными, но он остановился на первом :.

Пробовал использовать ||, и это сработало, но я хочу знать почему.

Надеюсь, вам все это ясно.

+0

* Шарфы были рядом * Ни один из этих средств не был близок? Непонятно, что вы на самом деле хотите здесь. – Liam

+3

'! (A && b)' эквивалентно '! A || ! b' –

ответ

2

Это просто логика: все выражение в сочетании с and is true только при условии, что обе части true.

Итак, когда ваша петля встретила первый символ :, выражение false и цикл был остановлен.

На основании вашего описания, ваш код должен выглядеть

while (!(json[z-2] == 's' && json[z] == ':')) 
{ z++; } 

или equivalentely

while (json[z-2] != 's' || json[z] != ':') 
{ z++; } 
+0

Итак, используя 'или', цикл не остановлен, пока оба они не являются «ложными»? –

+0

@EvaldasGrigaitis Да, поскольку выражение, объединенное символом 'или', является 'истинным', когда любая его часть является« истиной ». Похоже, вы должны обновить свои знания логических операторов. ;) –

+0

@EvaldasGrigaitis Подумайте об этом: если 'json [z] == ':'' истинно, тогда 'json [z-2]! = 'S' && json [z]! = ':'' Будет ложный. –

0

В C# есть 2 вида операторов:

  • операторы Сочетания: &&, ||
  • Битовые операторы: &, |

В контекстные операторы пропускают остальную часть выражения как только результат операции ясно, это означает, что:

  • для И: он оценивается до false, если какая-либо часть выражения оценивается как false

  • для OR: он вычисляет true, если какая-либо часть выражения вычисляется в true

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

Но иногда вы должны использовать побитовые операторы , особенно если вызываемые функции имеют побочные эффекты (они также используются для двоичных побитовых вычислений, но это не обсуждается здесь).

Пример:

int countEven = 0; 
int countOdd = 0; 

bool isEven(int x) 
{ 
    countEven++; 
    return (x % 1)==0; 
} 


bool isOdd(int x) 
{ 
    countOdd++; 
    return (x % 1) != 0; 
} 

Теперь, если у вас есть

var a=5; 
    var expression = (a==4) && (isEven(2) || isOdd(1)); 
    Console.WriteLine($"Expression result: {expression}"); 
    Console.WriteLine($"Even calls: {countEven}, Odd calls: {countEven} "); 

Вы получите 0 для countEven, а также для countOdd, поскольку функции isEven(2) и isOdd(1) никогда не называются.

Изменить что:

var expression = (a==4) & (isEven(2) | isOdd(1)); 

и функции будут вызываться, так countEven и CountOdd в настоящее время увеличивается.

Конечно, побочных эффектов (как показано выше) следует избегать, но я надеюсь, что разница сейчас понятна.

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