Skip to Content
Course content

10: Operators and Expressions

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Wait, why is 7 / 2 giving me 3 instead of 3.5?

This is probably the most common "gotcha" when you first start working with C++ expressions. The deal is that C++ looks at the types of the operands to decide which version of the operator to use. If you divide an integer by an integer, C++ performs integer division, which means it simply throws away the remainder. It doesn't round; it truncates.

I've seen plenty of bugs where someone tried to calculate a percentage—like (currentHealth / maxHealth) * 100—and it always returned 0 because currentHealth was smaller than maxHealth. To fix this, you need to "promote" one of the values to a floating-point type. You can do this with a static_cast or by multiplying by a double first.

int currentHealth = 45;
int maxHealth = 100;

// This will be 0 because 45/100 is 0 in integer math
double percentWrong = (currentHealth / maxHealth) * 100; 

// This works because we cast one to double, forcing floating-point division
double percentRight = (static_cast<double>(currentHealth) / maxHealth) * 100; 

Do ++i and i++ actually do different things?

In a basic for loop, you won't notice a difference. But when you use them inside another expression, the timing of the increment changes everything. I like to think of it this way: ++i (prefix) says "increment me, then give me the new value." i++ (postfix) says "give me the current value, then increment me in the background."

It’s a subtle distinction, but it can lead to some weird bugs if you're not paying attention. Check this out:

int energy = 10;
int use1 = ++energy; // energy becomes 11, then use1 becomes 11

int energy2 = 10;
int use2 = energy2++; // use2 becomes 10, then energy2 becomes 11

In modern C++, for complex types (like iterators you'll encounter later), prefix ++i is generally preferred because it doesn't have to create a temporary copy of the object before incrementing it. It's just a good habit to get into now.

How does C++ decide which operator to run first in a long expression?

You've probably heard of "operator precedence," which is basically the C++ version of PEMDAS from math class. Multiplication and division happen before addition and subtraction. Logical AND (&&) happens before logical OR (||).

However, relying on memory for the entire precedence table is a recipe for disaster. I'll tell you a secret: professional engineers use parentheses liberally. Even if you know that * comes before +, wrapping the operation in parentheses makes your intent clear to anyone else reading your code—and it saves you from having to double-check the manual at 2 AM.

// Ambiguous or mentally taxing
bool canAttack = health > 0 && ammo > 0 || hasMeleeWeapon;

// Clear and explicit
bool canAttack = (health > 0 && ammo > 0) || hasMeleeWeapon;

What is the modulo operator actually useful for?

The modulo operator (%) returns the remainder of an integer division. On the surface, it seems like a math curiosity, but in actual software engineering, we use it constantly. The most common use case is "wrapping" a value—making sure a number stays within a certain range.

For example, if you're building a game and you have a list of 4 different enemy types, you can use modulo to cycle through them indefinitely as you spawn new ones, regardless of how high your spawn counter goes.

int enemyTypesCount = 4;
for (int i = 0; i < 10; ++i) {
    int typeIndex = i % enemyTypesCount; 
    // typeIndex will cycle: 0, 1, 2, 3, 0, 1, 2, 3, 0, 1...
}

It's also the gold standard for checking if a number is even or odd: if (num % 2 == 0).




📋 Practical Task

Exercise: Combat Damage and Critical Hit Calculator

Your task is to build a small combat logic snippet. You need to simulate a hit where the damage is modified by a critical hit system and a defense reduction.

  • Create an integer variable for baseDamage (e.g., 25) and defensePower (e.g., 10).
  • Create an integer hitCount that tracks how many times the player has attacked.
  • The Logic: A "Critical Hit" occurs every 3rd attack. Use the modulo operator to determine if the current hitCount is a critical hit.
  • If it is a critical hit, double the baseDamage.
  • Subtract the defensePower from the damage to get the finalDamage.
  • Ensure that finalDamage cannot be negative (if defense is higher than damage, it should just be 0).
  • Print the result for a sequence of 5 attacks, showing whether each hit was "Normal" or "Critical" and the final damage dealt.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.