Jussi Hietanen
Jussi Hietanen

Reputation: 281

Very confusing while-loop condition

We have a school task to remove C-comments from a C code file.

There is an approach for this task to go through the input file and loop until the block comment end

*/

comes.

Why does this code work,

while(!(input[i] == '*' && input[i+1] == '/'))
{
  i++;
}

But this does not?

while(input[i] != '*' && input[i+1] != '/')
{
  i++;
}

The second variation never even goes into the loop for some reason. I tried to think around it but couldn't find the cause for why don't they work identically.

Upvotes: 0

Views: 526

Answers (5)

GokRix
GokRix

Reputation: 65

Your questions could be answered by putting them in a truth table

while(!(input[i] == '*' && input[i+1] == '/'))
{
  i++;
}

produces a truth table of a NAND gate

input[i]  input[i+1] Output
    0          0       1  
    0          1       1  
    1          0       1
    1          1       0

Whereas

while(input[i] != '*' && input[i+1] != '/')
{
  i++;
}

produces a truth table of a NOR gate

input[i]  input[i+1] Output
    0          0       1  
    0          1       0  
    1          0       0
    1          1       0

Now you can easily see why the two while loop produces two different results.

Upvotes: 1

chrillelundmark
chrillelundmark

Reputation: 345

At the first statement you test...

(input[i] == '*' && input[i+1] == '/')

When that evaluates to !true you enter the loop. For this to be !true one of your expressions need to fail.

In the second statement you test...

input[i] != '*' && input[i+1] != '/'

When this evaluates to true you enter the loop. For this to happen you need to both your expressions to success.

Upvotes: 0

unalignedmemoryaccess
unalignedmemoryaccess

Reputation: 7441

!(something AND something) are NAND gates, and they can be expressed to !something OR !something

So in your case

while (!(input[i] == '*' && input[i+1] == '/')) {

is the same as

//Pick your syntax from these 2 options
while (input[i] != '*' || input[i+1] != '/')
while (!(input[i] == '*') || !(input[i+1] == '/'))

How transition from AND to OR works.

Consider now you have NAND which are AND gates following NOT gates with inputs X and Y. The result is negated AND of both inputs. To separate both inputs to OR, you have to do these steps:

     ____      __
x --|    \    |  \
    | AND |---|NOT|--- (NAND)
y --|____/    |__/
  • Change AND to OR
  • Remove NOT by either remove gate or negate output again
  • Negate each input separatelly

And then you get:

x --- NOT GATE --- \ 
                      -- OR GATE -- NOT (from NAND) -- NOT (negate output)
y --- NOT GATE --- /
  • If you want to do opposite, you can do it (NOR and AND), just swap OR and AND again and all other steps.

Upvotes: 3

JTeam
JTeam

Reputation: 1505

it should be OR and not AND,

while (input[i] != '*' || input[i+1] != '/')

if i is not star * then it cannot be block comment. if i is star * then if i+1 is not slash '/' then it cannot be block comment.

Upvotes: 0

Aakash Verma
Aakash Verma

Reputation: 3994

The loop test condition has an AND expression where the first or left side of the expression is evaluated first to see if we need to check the second one also (If it is false, that means we don't need to check the second one as False && anything = False).

Here, the first condition is input[i] != '*'. That is why when the character is not * at the beginning of the line, the loop exits at the first execution itself.

Upvotes: 0

Related Questions