I have some questions about the logical not operator in C++ and Visual C++. I have posted another question relating to the logical not operator. I just can't seem to wrap my head around the uses of this operator. From what I have read so far the logical not operator can switch the value of bool variable and this in particular I don't seem to understand. Consider the code below.

// Soln4_4.cpp : main project file.

#include "stdafx.h"

using namespace System;

// This uses an array of bool values to record which data values
// have been output at any given time. A value that has been output
// is marked as true in the used array, and only values that have a 
// corresponding true value in the used array are checked each time.

int main(array<System::String ^> ^args)
{
  Random^ generator = gcnew Random;
  array<int>^ values = gcnew array<int>(generator->Next(10,20));

  // Initialize the array of data value
  for (int i = 0 ; i < values->Length ; i++)
    values[i] = generator->Next(100,1000);

  // Create array to identify elements that have been output
  array<bool>^ used = gcnew array<bool>(values->Length);
  Array::Clear(used, 0, used->Length);      // Set elements false

  Console::WriteLine(L"There are {0} values.", values->Length);


  int minimum = 0;                          // Current minimum
  int minIndex = 0;                         // Index of current minimum

  // Output the values in ascending sequence
  for(int count = 0 ; count<values->Length ; count++)
  {
    // Find first candidate for minimum
    for(int i = 0 ; i<values->Length ; i++)
      if(minimum == 0 && !used[i])
      {
        minimum = values[i];
        minIndex = i;
        break;
      }
    // Look for a lower minimum from remaining elements    
    for(int i = minIndex+1 ; i<values->Length ; i++)
      if(minimum>values[i] && !used[i])
      {
        minimum = values[i];
        minIndex = i;
      }

    used[minIndex] = true;                 // Record minimum as used
    Console::Write(L"{0,10}", minimum);    // Write the minimum
    if((count+1)%5 == 0)                   // If it's multiple of 5
      Console::WriteLine();                // Write a newline

    minimum = 0;                           // Reset minimum to 0
  }
  Console::WriteLine();
  return 0;
}

The part I don't understand is the line
if(minimum == 0 && !used)
{
.....
}
the !used is "notting" an array value that are all initially set to false so the !used should set it to true or rather this line is saying something like do this if minimum is equal to zero and element i is true or flagged as used in the used array. But this doesn't make sense because if that is true then this condition will never evaluate to true because the array has all false values initially. But the code works and does what it is supposed to which, is to sort the unsorted random array. So obviously I am missing a fundamental part of the logical not operator. I would assume that I am inferring the opposite meaning of that particular line because if I read it as false instead of true the code seems to work from logical standpoint. So... What does this !used mean if used[] is an array of all bool values all set to false by the clear function????

>So obviously I am missing a fundamental part of the logical not operator.
Let's break it down, starting with the if statement:

if ( ... ) {
  ...
}

If the condition is true, execute the block. Simple, right? Now let's add a boolean test:

if ( x < y ) {
  ...
}

If the result of x < y is true, execute the block. Or in more typical terms, if x < y, execute the block. Still simple, no? What about if we put the result of that boolean test in a boolean variable?

bool test = x < y;

if ( test ) {
  ...
}

If the condition evaluates to true, execute the block. The condition is an expression containing only a boolean variable whose value is the result of the test x < y. The current value of the variable acts as the condition. If the variable is true (ie. x < y), the block will be executed, otherwise it won't. Still simple, right? Now let's start negating:

bool test = x < y;

if ( !test ) {
  ...
}

If the condition evaluates to true, execute the block. The condition is still an expression containing only a boolean variable whose value is the result of the test x < y. But now we've negated that value, so if x < y, the block won't be executed because x < y is true, and negated it becomes false. In other words, the block will only be executed if the value of the condition is false before being negated. It's easier to see by returning to the basic expression:

if ( !( x < y ) {
  ...
}

It all comes down to the values. Even a variable by itself is an expression, and that expression has a value. Put the values together and you can figure out even the most convoluted of expressions.

There's a pattern you'll see often when it comes to relational operators. Negating the result of < gives you >= and negating >= gives you <. So the above if statement could be written identically as:

if ( x >= y ) {
  ...
}

All relational expressions can be reduced to either true or false in this way. Of course, once you get into the logical ANDs and ORs, short circuiting can throw you off, but that's a lesson for another day. :)

Comments
Indeed it is
Awesome help, good answers, got to the root of my problem with excellent examples.

God, this is why there are forums. I spent a quite a few minutes last night, trying to hash out what you explained there. Why couldn't the book have given me those three examples when explaining the logical not operator? That was the most clear-cut and precise answer to my question that I was able to find anywhere on the net. Thank you! I now, perfectly understand how to use the operator. Now I can add that to my arsenal and use if with confidence.

// in Soln4_4.cpp : main project file.

My problem is I do not understand the following statement

50. used[minIndex] = true; // Record minimum as used

boolean array used[] can sort it's elements when we set "True" ?

Edited 5 Years Ago by pkunzip1234: n/a

i finally find why need to set "used[minIndex] = true;",because

" if(!used && minimum > values)"
when "used[minIndex] = true;" then !used == false

It making the marked value is not to articipate in sorting
in values[].

This question has already been answered. Start a new discussion instead.