C++ Operators: Arithmetic, Comparison and Logic
Read C++ arithmetic, comparison and logical operators. Trace precedence, integer quotient and remainder, short-circuit safety and named conditions with boundary tests.
What you will learn
- Distinguish arithmetic, assignment and comparison.
- Use parentheses to express intentional grouping.
- Translate a requirement into named Boolean conditions.
- Explain built-in && and || short-circuiting.
- Test exact boundaries and protect unsafe operations.
An expression computes a value, not a requirement
An expression combines operands and operators to produce a value, and some expressions also have effects. A requirement such as 'delivery is allowed inside the area when the order qualifies' is not yet a C++ expression. First identify the facts, units and decisions. Then select operations that match them. This avoids writing a compact formula whose punctuation is valid but whose policy is different from the one you intended.
Arithmetic operators include addition, subtraction, multiplication, division and integer remainder. Comparisons such as <, <=, == and != produce bool values. Assignment uses = to update an object; equality uses == to compare values. Confusing the two can turn a condition into a state change. Keep comparisons and updates separate while learning, and enable warnings so the compiler can flag suspicious expressions without pretending warnings prove the business rule.
The same symbol can have different meanings in different contexts. << inserts values when used with std::cout; for integer operands it is a bit-shift operator. This lesson uses stream insertion only for output and postpones bit manipulation. Similarly, a minus sign can negate one operand or subtract two operands. Read an operation together with its operands and types rather than assigning one universal meaning to each character.
Grouping changes the calculation
Multiplication, division and remainder bind more tightly than addition and subtraction. Thus 2 + 3 * 4 means 2 + (3 * 4), producing fourteen, while (2 + 3) * 4 produces twenty. Parentheses document a deliberate grouping and can make a policy easier to read even when precedence already produces the intended result. They do not compensate for incorrect units or an inappropriate operand type.
For nonnegative counts, quotient and remainder help distribute whole items into equal groups. Seventeen items in groups of five produces three complete groups and two remaining items. State that the group size must be positive before evaluating either operation. Negative operands have different interpretation concerns, and integer overflow remains possible even when the operators are familiar. The examples use small validated values so the arithmetic contract is visible.
Compound assignment such as total += amount updates total using the operation. Increment and decrement also modify state. Their prefix and postfix forms differ in the value produced by the expression. Until a loop needs them, keep updates on separate statements and avoid reading and modifying the same object several times in one expression. Operator precedence describes parsing; it is not a general guarantee that every operand is evaluated left to right.
Predict grouping and leftover items
Run these supported integer operations. Change items to zero or eighteen and predict the quotient and remainder before running.
Predict the output, edit the source, then select Run code.
Compare with the starter's expected output
Groups: 3
Leftover: 2
Unparenthesized: 14
Grouped: 20
After editing inputs, calculate a new prediction; this reference describes only the starter.
Name the conditions before combining them
A bool holds true or false. A comparison gives a Boolean result that can be named, such as const bool withinArea{distanceKm <= 10}. The name should describe what the result means, not restate punctuation. Naming conditions makes a complex decision reviewable one piece at a time. It also gives your debugger useful intermediate observations when the final answer is wrong despite a successful build.
Built-in && means both conditions must be true; || means at least one must be true; ! negates a Boolean condition. For our delivery policy, withinArea && (qualifyingOrder || member) requires the geographic rule regardless of membership. Without those parentheses, withinArea && qualifyingOrder || member groups differently because && binds more tightly than ||. A member outside the area could qualify under that changed policy. The code would compile while expressing the wrong requirement.
Do not translate a mathematical interval as 0 <= age <= 120. C++ evaluates the first comparison to a Boolean value, then compares that result with 120; it does not create the intended interval test. Write age >= 0 && age <= 120. Also distinguish && from &: the latter is not the logical short-circuit operator taught here. A familiar-looking mathematical notation or single-character shortcut can silently answer a different question.
Trace a delivery eligibility rule
The member is outside the area, so eligibility must remain false. boolalpha prints readable true/false words instead of the default numeric form.
Predict the output, edit the source, then select Run code.
Compare with the starter's expected output
Within area: false
Eligible: false
After editing inputs, calculate a new prediction; this reference describes only the starter.
Short-circuiting can protect a later operation
For built-in &&, the left operand is evaluated first. If it is false, the right operand is not evaluated. For built-in ||, a true left operand skips the right operand. This matters when the right side has a precondition. count != 0 && total / count > 2 avoids evaluating the division when count is zero. Reversing those operands defeats the guard because the unsafe operation would occur first.
Short-circuiting is not a substitute for a complete numeric safety analysis. A nonzero divisor alone does not make every signed integer division safe: the minimum signed value divided by minus one can be unrepresentable. Our small nonnegative counts avoid that additional case. State those bounds explicitly instead of claiming one comparison handles every possible int input. For a fractional threshold, choose floating-point operands intentionally rather than inheriting integer truncation.
Do not hide an essential state update on the right of a logical operator and assume it always occurs. The skip behavior is exactly what makes the guard useful. Named pure conditions are easier to test than a chain of assignments, increments and function calls with side effects. Overloaded operators on user-defined types have further rules; this lesson's short-circuit explanation applies to the built-in Boolean operators, not arbitrary classes with similarly named operations.
Observe a skipped division
count is zero. The false left condition prevents evaluation of the integer division on the right. Run it in the compiler-backed editor or with your local compiler.
Predict the output, edit the source, then select Run code.
Compare with the starter's expected output
Above two: false
After editing inputs, calculate a new prediction; this reference describes only the starter.
Test decisions with facts, not only one happy case
Create a small truth table in your notes: an order inside the area and above the threshold qualifies, an inside-area member with a smaller order qualifies, an inside-area nonmember with a smaller order does not, and an outside-area member does not. Those cases distinguish the intended policy from the unparenthesized alternative. Merely observing true for one large order would not expose the policy error.
Test distances nine, ten and eleven and order values 1999, 2000 and 2001. At the exact threshold, <= and >= include the boundary; < and > exclude it. Add zero and a negative distance as modeling cases rather than allowing nonsensical values by accident. Keep units consistent: comparing cents with a dollar threshold is a requirement error, not an operator-precedence problem. A review should connect each expression to one documented policy and one discriminating test.
Build and run the local examples
Save one complete example or lab solution as main.cpp. Choose your installed toolchain; run only after a successful build. Input examples wait for text in your terminal. The browser teaching interpreter does not support these full-language features.
macOS / Clang:
clang++ -std=c++20 -Wall -Wextra -Wpedantic main.cpp -o lesson
./lesson
Linux / GCC:
g++ -std=c++20 -Wall -Wextra -Wpedantic main.cpp -o lesson
./lesson
Windows Developer Command Prompt / MSVC:
cl /std:c++20 /EHsc /W4 main.cpp /Fe:lesson.exe
lesson.exeIndependent lab
Implement the delivery eligibility expression for a nonmember exactly on the distance and order boundaries. Then test the four policy combinations.
Acceptance checklist
- Use distanceKm 10, orderCents 2000 and member false.
- Require a nonnegative distance no greater than ten.
- Qualify an order at or above two thousand cents.
- Keep the OR group parenthesized inside the area requirement.
- Print Eligible: true and record tests for outside-area members and below-threshold nonmembers.
Need a hint?
- Write withinArea and qualifyingOrder first.
- Use boolalpha for the requested words.
- Change only one fact at a time around each threshold.
Write and run your lab
Build your own solution before revealing the reference. Use the input field for normal, boundary and invalid cases; this runner executes your program but does not grade it.
Predict the output, edit the source, then select Run code.
Your lab evidence and notes
Record predictions, actual output, commands and the cause of each repair. Code is plain text: this scratchpad does not execute or grade C++.
Loading local notes…
Review your acceptance checklist and quiz explanations before marking this lesson complete. This is self-review, not a grade or certification.
Reveal the explained lab solution
Reference lab solution
Compare the reference with your own reasoning. Running this solution does not grade or complete the lesson.
Predict the output, edit the source, then select Run code.
Expected output
Eligible: true
Both numeric boundaries are inclusive. The starter qualifies without membership because its order meets the threshold.
Membership bypasses only the order threshold, not the area rule. Distance eleven must still produce false.
An inside-area nonmember with 1999 cents produces false. That case distinguishes >= from an accidentally lower threshold.
Review before moving on
Explain the lesson's objectives in your own words, compare your lab evidence with the acceptance checklist, and keep the first failing case alongside your repair. Completing a page is not proof that every C++ feature or input is supported.
- Distinguish arithmetic, assignment and comparison.
- Use parentheses to express intentional grouping.
- Translate a requirement into named Boolean conditions.
- Explain built-in && and || short-circuiting.
- Test exact boundaries and protect unsafe operations.
References and further reading
Original examples and exercises accompany these primary references. Tool-specific diagnostics and support depend on your installed version.