3. Expressions and Operators#
Expressions are any combination of one ore more literals, variables, function calls, and operators. An operator is a keyword or a symbol thats used to perform an operation such as addition.
3.1. Assignment#
An assignment statement calculates the value on the right side of equals statement, converts the value if necessary, and then replaces the object (memory location) of the left-hand side of the assignment with that value. A simple example follows:
1//filename: script0.cpp
2//complile: g++ -std=c++17 -o script0 script0.cpp
3//execute: ./script0
4#include <iostream>
5using namespace std;
6
7int main(int argc, char *argv[]) {
8 int i = 20;
9 int j = 4;
10
11 cout << "i: " << i << ", j: " << j << "\n";
12
13 i = j;
14
15 cout << "i: " << i << ", j: " << j << "\n";
16
17 return 0;
18}
Line 13 demonstrates the simple assignment. The value is read from the variable j and then written to i. As both variables are the same type, no conversion was necessary. The left operand in an assignment is typically referred to as an lvalue in C++. The term originates from it being the left operand. However, you may want to think of it as standing for locator value instead - the lvalue must designate an object (i.e., a location in memory). The right operand is always an expression and is referred to as an rvalue.
j = i + 15;
In the above line of code, the expression i + 15
is an rvalue. The i
(which can be an lvalue by itself) is converted into an rvalue as its value is read. The addition operation results in an rvalue that’s then assigned to the lvalue of j
.
The following line of code demonstrates an error as an rvalue must always by on the right side of the assignment operator.
10 = i; /* error: rvalue appears on the left-hand side of the assignment */
The assignment operation does return the rvalue in C++. Neither Python or Java return a value in an assignment statement/operation - this also prevents issues in boolean expressions and control statements.
3.2. Increment and Decrement Operators#
Unlike Python, C++ contains unary increment(++
) and decrement(--
) operators that can upon an lvalue - these operations either add 1 to a value or subtract 1. They can be either prefix operators, in which the operation comes first and then the resulting value is returned; or, postfix operators in which the initial value is returned and then the operation occurs.
int i = 5;
int result;
result = i++; /* result contains 5, while i now has 6 */
result = i--; /* result contains 6, while i now has 5 */
result = ++i; /* result and i both contain 6 */
result = --i; /* result and i both contain 5 */
3.3. Arithmetic Operators#
The following table lists the arithmetic operators available in C++. Unlike Python, there is no floor division. You will need to use casts depending on the resulting value desired.
Operator |
Meaning |
---|---|
* |
Multiplication |
/ |
Division |
% |
Remainder |
+ |
Addition (or unary plus) |
- |
Subtraction (or unary minus) |
1//filename: arithmetic.cpp
2//complile: g++ -std=c++17 -o arithmetic arithmetic.cpp
3//execute: ./arithmetic
4#include <iostream>
5using namespace std;
6
7int main(int argc, char *argv[]) {
8 int a = 9,b = 4;
9 int result;
10
11 result = a * b;
12 cout << "a * b = " << result << "\n";
13
14 result = a / b;
15 cout << "a / b = " << result << "\n";
16
17 cout << "a / b = " << (float) a / b << "\n"; /* results in a float value */
18
19 result = a % b;
20 cout << "a % b = " << result << "\n";
21
22 cout << "-3 % 9 = " << -3 % 9 << "\n"; /* NOTE: remainder, not modulo. Python produces 6 */
23
24 result = a + b;
25 cout << "a + b = " << result << "\n";
26
27 result = a - b;
28 cout << "a - b = %" << result << "\n";
29
30 return EXIT_SUCCESS;
31}
3.4. Shorthand Assignment Operators#
Similar to Python, C++ supports the expected shorthand assignment operators:
Operator |
Example |
Equivalent to |
---|---|---|
*= |
a *= b |
a = a * b |
/= |
a /= b |
a = a / b |
%= |
a %= b |
a = a % b |
+= |
a += b |
a = a + b |
-= |
a -= b |
a = a - |
3.5. Relational Operators#
In C++, relation operators compare two operands. A C did not originally have a boolean type, these operators return 1 for true and 0 for false. Relational operators are primarily used when making decisions in selector (if
, switch
) and iteration (while
, for
) statements.
Operator |
Meaning |
Example |
---|---|---|
== |
equals |
5 == 5 |
!= |
not equals |
5 != 6 |
> |
greater than |
6 > 5 |
>= |
greater than or equals |
4 >= 4 |
< |
less than |
4 < 5 |
<= |
less than or equals |
3 <= 3 |
1//filename: relation.cpp
2//complile: g++ -std=c++17 -o relation relation.cpp
3//execute: ./relation
4#include <iostream>
5using std::cout;
6using std::endl;
7
8int main() {
9 int a = 11, b = 5, c = 11;
10
11 cout << a << " == " << b << " is " << (int) (a == b) << "\n";
12 cout << a << " == " << c << " is " << (int) (a == c) << "\n";
13 cout << a << " > " << b << " is " << (int) (a > b) << "\n";
14 cout << a << " > " << c << " is " << (int) (a > c) << "\n";
15 cout << a << " < " << b << " is " << (int) (a < b) << "\n";
16 cout << a << " < " << c << " is " << (int) (a < c) << "\n";
17 cout << a << " != " << b << " is " << (int) (a != b) << "\n";
18 cout << a << " != " << c << " is " << (int) (a != c) << "\n";
19 cout << a << " >= " << b << " is " << (int) (a >= b) << "\n";
20 cout << a << " >= " << c << " is " << (int) (a >= c) << "\n";
21 cout << a << " <= " << b << " is " << (int) (a <= b) << "\n";
22 cout << a << " <= " << c << " is " << (int) (a <= c) << "\n";
23
24 return 0;
25}
3.6. Logical Operators#
C++ supports the same set of logical operators as Python, including short-circuit decisions. However rather than using the keywords of and
, or
, and not
, C++ uses the following symbols as operators:
Operator |
Alternative Spelling |
Meaning |
Example |
---|---|---|---|
&& |
and |
Logical AND. True only both operands are true. |
int i = 5int k = 5k == 5 && i == 4 evaluates to false |
|| |
or |
logical OR. True when one or both of the operands are true. |
k == 5 |
! |
not |
Logical NOT. True only if the operand is zero (0). |
!k evaluates to false |
Note: The C++ standard does allow alternative spellings for these operators.
1//filename: logic.cpp
2//complile: g++ -std=c++17 -o logic logic.cpp
3//execute: ./logic
4#include <iostream>
5using std::cout;
6using std::endl;
7
8int main() {
9 int a = 11, b = 5, c = 11, result;
10
11 result = (a == b) && (c > b);
12 cout << "(a == b) && (c > b) is " << result << "\n";
13
14 result = (a == b) && (c < b);
15 cout << "(a == b) && (c < b) is " << result << "\n";
16
17 result = (a == b) || (c < b);
18 cout << "(a == b) || (c < b) is " << result << "\n";
19
20 result = (a != b) || (c < b);
21 cout << "(a != b) || (c < b) is " << result << "\n";
22
23 result = !(a != b);
24 cout << "!(a != b) is " << result << "\n";
25
26 result = !(a == b);
27 cout << "!(a == b) is " << result << "\n";
28
29 return 0;
30}
3.7. Bitwise Operators#
C++ has a series of operators to support bit-wise operations. Typically, these are performed on integer types. Short-hand assignment operators do exist for these as well.
Operator |
Meaning |
Example |
---|---|---|
& |
AND operator. bit has to exist in both operands |
|
| |
OR. Bit exists in either operand |
|
^ |
XOR. Bit is set if the bit is set in one operand, but not both |
|
~ |
Binary complement |
|
<< |
Shift left operator |
|
>> |
Shift right operator |
1//filename: bitwise.cpp
2//complile: g++ -std=c++17 -o bitwise bitwise.cpp
3//execute: ./bitwise
4#include <iostream>
5using std::cout;
6using std::endl;
7
8
9std::string toBinaryString(int number) {
10 if (number == 0) { return "0"; }
11
12 std::string binary = "";
13 while (number > 0) {
14 binary = std::to_string(number % 2) + binary; // Add remainder at the front of string
15 number /= 2;
16 }
17
18 return binary;
19}
20
21void pBinary(int number, int num_digits) {
22 std::string binary = toBinaryString(number);
23 while (binary.length() < num_digits) {
24 binary = "0" + binary;
25 }
26 cout << binary;
27}
28
29int main() {
30 unsigned int a = 8;
31 unsigned int b = 8;
32 unsigned int c = 7;
33 unsigned int d = 1;
34
35 pBinary(a,4); cout << " & "; pBinary(a,4); cout << " = "; pBinary(a&b,4); cout << "\n";
36 pBinary(a,4); cout << " & "; pBinary(c,4); cout << " = "; pBinary(a&c,4); cout << "\n";
37 pBinary(a,4); cout << " | "; pBinary(c,4); cout << " = "; pBinary(a|c,4); cout << "\n";
38 pBinary(c,4); cout << " ^ "; pBinary(d,4); cout << " = "; pBinary(c^d,4); cout << "\n";
39 cout << "~"; pBinary(c,4); cout << " = "; pBinary(~c,4); cout << "\n";
40 pBinary(d,4); cout << " << 3"; cout << " = "; pBinary(d << 3,4); cout << "\n";
41 pBinary(a,4); cout << " >> 1"; cout << " = "; pBinary(a >> 1,4); cout << "\n";
42}
3.8. Operator Precedence#
Operator precedence determines how an expression is evaluated. C++ and Python follow largely the same rules. Use parenthesis whenever there might be any confusion on the ordering of operations.
Category | Operator | Associativity |
---|---|---|
Postfix | () [] -> . ++ - - | Left to right |
Unary | + - ! ~ ++ - - (type)* & sizeof | Right to left |
Multiplicative | * / % | Left to right |
Additive | + - | Left to right |
Shift | << >> | Left to right |
Relational | < <= > >= | Left to right |
Equality | == != | Left to right |
Bitwise AND | & | Left to right |
Bitwise XOR | ^ | Left to right |
Bitwise OR | | | Left to right |
Logical AND | && | Left to right |
Logical OR | || | Left to right |
Conditional | ?: | Right to left |
Assignment | = += -= *= /= %=>>= <<= &= ^= |= | Right to left |
Comma | , | Left to right |
3.8.1. Logical and Bitwise Operators#
While it may seem feasible to interchange the use of &&
and &
, you should avoid this practice. Use the logical operator (&&
) when comparing two expressions and testing that they both evaluate to true. Use the bitwise operator (&
) when comparing/performing bit-level operations. Don’t mix and match these operators - C++ will let you, but does it make semantic sense?
1//filename: logical_bit.cpp
2//complile: g++ -std=c++17 -o logical_bit logical_bit.cpp
3//execute: ./logical_bit
4#include <iostream>
5using std::cout;
6using std::endl;
7
8int main(int argc, char *argv[]) {
9 int i = 2;
10 int j = 4;
11 if (i && j) {
12 cout << "logical and: true, value " << (int) (i && j) << "\n";
13 }
14 if (i & j) {
15 cout << "bitwise and: true " << "\n";
16 }
17 else {
18 cout << "bitwise and: false, value " << (int) (i & j) << "\n";
19 }
20 return 0;
21}
3.8.2. char Arithmetic#
In Python, we did not have the ability to manipulate a character value - technically it was a string with just 1 character - we had to convert it to a number with the ord()
function. In C++, the char
data type is an integer type, typically of just a single character. As such we can directly perform arithmetic on the variables without performing any conversions.
1//filename: char.cpp
2//complile: g++ -std=c++17 -o char char.cpp
3//execute: ./char
4#include <iostream>
5using std::cout;
6using std::endl;
7
8int main(int argc, char *argv[]) {
9 char c = 'a'; /* 97 comes from the ASCII value for 'a' */
10 c += 5;
11
12 cout << "original value as int: " << (int) 'a' << "\n";
13 cout << "Value after addition as int: " << (int) c << "\n";
14 cout << "Value after addition as char: "<< c << "\n";
15
16 return 0;
17}