← Back to C++ Course | Chapter 3: Operators | Lesson 4 of 9

C++ Logical Operators

Logical operators combine true-or-false questions, like 'you can go out if it is sunny AND homework is done'. && means and, || means or, and ! means not.
Syntax
cpp
condition1 && condition2  // AND
condition1 || condition2  // OR
!condition                // NOT

Logical AND (&&)

&& (logical AND) evaluates to true only when both surrounding expressions are true, making it the right choice whenever a condition genuinely requires two things to hold simultaneously, like if (age >= 18 && hasID).

If either side is false, the whole expression is false regardless of the other.

Example: Logical AND (&&)

cpp
// Include std::cout and std::cin
#include <iostream>

// Program execution starts in main()
int main() {
	// Declare age and set it to 20
	int age = 20;
	// Declare hasID and set it to true
	bool hasID = true;
	// Check whether age >= 18 && hasID
	if (age >= 18 && hasID) {
		// Print to the console with cout
		std::cout << "Access granted" << std::endl;
	}
	// Return 0 to signal that the program finished successfully
	return 0;
}

Logical OR (||)

|| (logical OR) evaluates to true if at least one of the two expressions is true, useful whenever any one of several conditions is enough to proceed, like if (isAdmin || isOwner). It only evaluates to false when both sides are false.

Example: Logical OR (||)

cpp
// Include std::cout and std::cin
#include <iostream>

// Program execution starts in main()
int main() {
	bool isAdmin = false, isOwner = true;
	// Check whether isAdmin || isOwner
	if (isAdmin || isOwner) {
		// Print to the console with cout
		std::cout << "Access granted" << std::endl;
	}
	// Return 0 to signal that the program finished successfully
	return 0;
}

Logical NOT (!)

! (logical NOT) flips a boolean's value, turning true into false and vice versa, and is most often used to invert a condition cleanly, like if (!isEmpty(list)) reading naturally as 'if the list is not empty'.

Overusing double negatives with ! can hurt readability, so it's worth naming boolean variables so the positive case reads clearly.

Example: Logical NOT (!)

cpp
// Include std::cout and std::cin
#include <iostream>

// Program execution starts in main()
int main() {
	// Declare isEmpty and set it to false
	bool isEmpty = false;
	// Check whether !isEmpty
	if (!isEmpty) {
		// Print to the console with cout
		std::cout << "List is not empty" << std::endl;
	}
	// Return 0 to signal that the program finished successfully
	return 0;
}

Combining Logical Operators

Complex conditions can chain multiple && and || operators together, and since C++ evaluates && before || by default (similar to how * binds tighter than +), parentheses are essential whenever you need to make the intended grouping explicit rather than relying on default precedence.

Example: Combining Logical Operators

cpp
#include <iostream>

int main() {
	bool a = true, b = false, c = true;
	if ((a || b) && c) { // parentheses make the grouping explicit
		std::cout << "Condition met" << std::endl;
	}
	return 0;
}

Short-circuit Evaluation

C++ uses short-circuit evaluation: in a && b, if a is false the entire expression is already known to be false, so b is never evaluated at all — the same applies to a || b when a is true.

This isn't just an optimization; it's commonly used deliberately, as in if (ptr != nullptr && ptr->value > 0), where the null check must run first to make the second check safe.

Example: Short-circuit Evaluation

cpp
#include <iostream>

int main() {
	int* ptr = nullptr;
	if (ptr != nullptr && *ptr > 0) { // null check runs first, safely
		std::cout << "Positive" << std::endl;
	} else {
		std::cout << "Skipped dereference safely" << std::endl;
	}
	return 0;
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Using & instead of && for a logical AND, which is a bitwise operator and can give unexpected results.
  2. Writing if (x == 1 || 2), which is always true because 2 is non-zero; you must write x == 1 || x == 2.
  3. Relying on the right side of && or || always running, when short-circuiting may skip it and any side effects in it.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.