Arithmetic and Assignment Operators
Explore how to manipulate data using arithmetic and assignment operators in C++. Learn the rules of integer and floating-point division, use compound assignment operators for efficient updates, and understand the difference between prefix and postfix increments. Gain essential skills to perform accurate calculations and avoid common pitfalls like undefined behavior.
Mathematics is the engine behind almost every program, whether we are calculating damage in a game, processing financial transactions, or resizing an image. C++ provides a robust set of operators to handle these tasks efficiently. However, unlike standard algebra, C++ math has specific rules regarding types and evaluation order.
In this lesson, we will learn how to manipulate data using arithmetic and assignment operators, ensuring our calculations are both correct and efficient. These are some of the most common operators in C++ and form the foundation of numeric computation and variable updates.
Basic arithmetic operators
Arithmetic operators allow programs to perform basic math operations on values, forming the foundation of most calculations. C++ provides five fundamental arithmetic operators:
Addition (
+): It adds two values together. It is commonly used to combine values, update counters, or calculate totals.Subtraction (
-): It finds the difference between two values. This is often used when decreasing values or calculating remaining amounts.Multiplication (
*): It multiplies two values. It is useful for scaling values or performing repeated addition.Division (
/): It divides one value by another. Remember that when used with integers, the result is also an integer, and any decimal part is discarded. To get a decimal result, at least one operand must be a floating-point value.Modulus (
%): It gives the remainder after division. It works only with integers and is commonly used to check divisibility or determine whether a number is even or odd.
Let's see them in action below.
Lines 4-6: We initialize two
inttype variables:num1andnum2. Next, we initialise afloattype variable,num3.Line 8: We add
num1andnum2using+operator and print its value directly without storing result in a separate variable.Line 9: We subtract
num2fromnum1using-operator and print its value directly without storing result in a separate variable.Line 10: We multiply
num1withnum2using*operator and print its value directly without storing result in a separate variable.Line 11: We divide
num1withnum2using/operator and print its value directly without storing result in a separate variable. Note, it prints2and not2.5. That's because when/is used with integers, the result is also an integer, and any decimal part is discarded.Line 12: Now, we try dividing
num3withnum2using/operator and print its value directly without storing result in a separate variable. Note, it prints2.5. That's because to get a decimal result, at least one operand must be a floating-point value. We can also try this withdoubletype variable.Line 13: We get remainder after dividing
num1withnum2using%operator and print its value directly without storing result in a separate variable. Try replacingnum1withnum3, and notice the compilation error because this this operator only works with integers.
Assignment and compound assignment
We often update a variable based on its own current value; for example:
x = x + 1;
It is a very common use case. C++ provides a shortcut to write this through compound assignment operators. These operators apply the arithmetic operation and update the variable in a single step. Below table enlists commonly used compound assignment operators.
Operator | Usage | Equivalence |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Let's see them in action below:
Let’s break this down step by step:
Lines 4: We declare an integer variable
wallet, initializing it to100.Lines 6–9: Here, we use compound assignment operators, which combine an arithmetic operation with assignment. Each of these statements updates
walletin place.:wallet += 50;adds50towallet, resulting in150.wallet -= 20;subtracts20from the current value, resulting in130.wallet *= 2;multiplies the value by2, resulting in260.wallet /= 10;divides the value by10. Sincewalletis anint, this is integer division, producing26.
Line 11: We print the final value of
walletto the console.
Deep dive: The order of compound assignment
A common source of confusion for beginners is how compound assignment operators interact with other arithmetic on the same line. Take this expression as an example:
x += 5 * 2;
At first glance, you might wonder whether this means (x + 5) * 2 or x + (5 * 2). The correct interpretation is the second one. In C++, the entire right-hand side (RHS) is evaluated first, and only then is the compound assignment applied. This happens because compound assignment operators like += and *= have very low precedence.
So in the case of x += 5 * 2, the compiler first evaluates 5 * 2, which results in 10. Only after that does it apply the compound operation, effectively turning the statement into x = x + 10. If x started as 10, the final result is 20.
This rule holds even when the right-hand side contains operators with lower precedence, such as addition. Consider this example:
int y = 4;y *= 2 + 3;
It’s easy to mistakenly read this as y = y * 2 + 3, which would evaluate to 11. However, that’s not what happens. Instead, the expression 2 + 3 is evaluated first, producing 5. Then the compound assignment is applied, resulting in y = 4 * 5, which gives 20.
A helpful way to think about compound assignment is to imagine implicit parentheses around the entire right-hand side. In other words, y *= 2 + 3 behaves as if it were written y *= (2 + 3). Keeping this mental model in mind can help you avoid subtle and confusing bugs.
Increment and decrement operators
Adding or removing 1 is the most frequent math operation in programming. C++ provides dedicated operators for this:
Increment (
++): Adds 1 to a variable.Decrement (
--): Subtracts 1 to a variable.
These come in two forms: prefix and postfix. Prefix means to increment/decrement the variable first, then returns the new value. It's also read as, "Change, then use." Whereas, postfix means to makes a copy of the old value, increments the variable, then returns the copy. It's read as, "Use, then change."
Let’s break this down into steps:
Lines 7–8: These lines demonstrate the difference between prefix and postfix increment operators:
++ais the prefix increment. The value ofais incremented before it is used, soabecomes6, andprefix_resultreceives6.b++is the postfix increment. The current value ofbis used first, sopostfix_resultreceives5, and thenbis incremented to6.
Lines 10–11: We print the final values of
aandb, along with the values that were assigned during the increment operations. This clearly shows how prefix and postfix increments behave differently.
Try replacing ++ with the decrement operator to see the updated results.
Undefined behavior: The side effect trap
A "side effect" is any modification of a variable (like ++ or =). In C++, never modify the same variable twice in a single statement. The compiler does not guarantee the order of operations, leading to an undefined behavior.
This code is dangerous because the variable i is modified and read in the same expression: i++ + i. The compiler is allowed to evaluate parts of this expression in different orders, so it’s unclear whether i is incremented before or after it’s used in the addition. This makes the result unpredictable and dependent on the compiler.
The golden rule: Never modify a variable more than once in a single expression, and do not use a variable that is being modified in the same expression.
Operator of precedence
Operator precedence is about grouping. It determines how an expression is parsed and which operators bind more tightly than others. It affects how the expression is interpreted, not the sequence in which code runs. For example,
Line 8: In the expression
a + b * c, multiplication has higher precedence than addition, sob * cis grouped together first.Line 9: In case, we want to group
a + bfirst, we need to enclose it in parentheses. Remember that()has the highest precedence amongst any of the arithmetic operators.
Summary of best practices
Use parentheses: Don't memorize the entire precedence table. If you write
a + b & c, use parentheses(a + b) & cto be sure.Compound assignment is safe:
x *= a + bsafely calculatesa + bfirst.Prefix over postfix: Prefer
++iunless you explicitly need the old value.
We now possess the tools to calculate, count, and manipulate data precisely. We understand the specific behaviors of integer versus floating-point division and how to use increment operators safely. In the next lesson, we will combine these math skills with logical operators to make decisions in our code.