# Chapter 5 - Notes

## Statements

* Statements are executed one after another&#x20;
* All statements in C++ end with a semicolon (;)
* **Whitespaces do not matter** in C++, so multiple statements can exist in a single line.&#x20;

## Blocks&#x20;

* A compound statement (or block) is grouped together within braces `{ ... }`
* A block groups one or more statements indicating that they belong together.&#x20;
* This is also referred to as a **scope**.

## Operators&#x20;

### Mathematical Operators&#x20;

| Operator | Name                    | Description                                                                   |
| -------- | ----------------------- | ----------------------------------------------------------------------------- |
| `=`      | Assignment operator     | **Assigns** the value of the RHS to the LHS, and returns the value of the LHS |
| `+`      | Addition operator       | **Adds** the RHS value to the LHS, returns the result of the operation        |
| `-`      | Subtraction operator    | **Subtracts** the RHS from the LHS, returns the result of the operation       |
| `*`      | Multiplication operator | **Multiplies** the LHS by the RHS, returns the result of the operation        |
| `/`      | Division operator       | **Divides** the LHS by the RHS, returns the result of the operation           |
| `%`      | Modulus operator        | **Divides** the LHS by the RHS, returns the **remainder of the division**     |

### Increment & Decrement Operators&#x20;

| Operator     | Name                    | Description                                                                      |
| ------------ | ----------------------- | -------------------------------------------------------------------------------- |
| `variable++` | Post-increment operator | **Increments** `variable` by one, and returns the value **before** incrementing. |
| `++variable` | Pre-increment operator  | **Increments** `variable` by one, and returns the value **after** incrementing.  |
| `variable--` | Post-decrement operator | **Decrements** `variable` by one, and returns the value **before** decrementing. |
| `--variable` | Pre-decrement operator  | **Decrements** `variable` by one, and returns the value **after** decrementing.  |

### Comparison Operators&#x20;

| Operator | Name                              | Description                                                                |
| -------- | --------------------------------- | -------------------------------------------------------------------------- |
| `==`     | Equal-to operator                 | Returns **true** if the LHS value **is equal** to the RHS value            |
| `!=`     | Not-equal-to operator             | Returns **true** if the LHS value **is not equal** to the RHS value        |
| `<`      | Less-than operator                | Returns **true** if the LHS value **is less** than the RHS value           |
| `<=`     | Less-than-or-equal-to operator    | Returns **true** if the LHS value **is less or equal to** the RHS value    |
| `>`      | Greater-than operator             | Returns **true** if the LHS value **is** **greater** than the RHS value    |
| `>=`     | Greater-than-or-equal-to operator | Returns **true** if the LHS value **is greater or equal to** the RHS value |

### Logical Operators&#x20;

For all the below examples, we use `1` to mean '**True**', and `0` to mean '**False**'.

* The **NOT operator** is used by prefixing a boolean value with '`!`' :

| Operator    | Value of `variable` | Result | Description                          |
| ----------- | ------------------- | ------ | ------------------------------------ |
| `!variable` | `1`                 | `0`    | The value of `variable` is inverted. |
| `!variable` | `0`                 | `1`    | The value of `variable` is inverted. |

{% hint style="success" %}
The result of `!variable` returns the **opposite of the value currently held** by `variable`.
{% endhint %}

* The **AND operator** is used by using '`&&`' between two boolean values:

| Operator | Value of `x` | Value of `y` | Result |
| -------- | ------------ | ------------ | ------ |
| `x && y` | `1`          | `0`          | `0`    |
| `x && y` | `0`          | `1`          | `0`    |
| `x && y` | `0`          | `0`          | `0`    |
| `x && y` | `1`          | `1`          | `1`    |

{% hint style="success" %}
The result of `x && y` evaluates to true **if and only if both `x` and `y` are true.**&#x20;
{% endhint %}

* The **OR operator** is used by using '`||`' between two boolean values:

| Operator   | Value of `x` | Value of `y` | Result |
| ---------- | ------------ | ------------ | ------ |
| `x \|\| y` | `1`          | `0`          | `1`    |
| `x \|\| y` | `0`          | `1`          | `1`    |
| `x \|\| y` | `0`          | `0`          | `0`    |
| `x \|\| y` | `1`          | `1`          | `1`    |

{% hint style="success" %}
The result of `x || y` evaluates to true **if either `x` or `y` are true.**&#x20;
{% endhint %}

### Bitwise Operators&#x20;

#### Bitwise NOT (\~)

* A bitwise NOT inverts every bit in the bit set

```cpp
uint8_t a = 152;  // 1001 1000
uint8_t b = ~a;  //  0110 0111  (Every bit in `a` has been inversed)

std::cout << unsigned(a) << std::endl;  // This prints 152
std::cout << unsigned(b) << std::endl;  // This prints 103
// Note: the `unsigned` is to have the program print it as a number 
//       instead of a character
```

#### Bitwise AND (&)

* A bitwise AND performs an AND operation for each bit between two numbers.&#x20;

```cpp
uint8_t a = 100;    // 0110 0100
uint8_t b = 200;    // 1100 1000
uint8_t c = a & b;  // 0100 0000  (This is 64)

// Each bit in `c` is set *if and only if* 
// the bit in `a` AND the bit in `b` were 1.
```

{% hint style="success" %}
Each bit in `c` is set **if and only if** the corresponding bits in **both** `a` **and** `b` **were set**&#x20;
{% endhint %}

#### Bitwise OR (|)

* A bitwise OR performs an OR operation for each bit between two numbers.&#x20;

```cpp
uint8_t a = 150;   // 1001 0110
uint8_t b = 220;   // 1101 1100
uint8_t c = a & b; // 1101 1110 (This is 222)

// Each bit in `c` is set if *either* 
```

{% hint style="success" %}
Each bit in `c` is set if the corresponding bits in **either** `a` **or** `b` **were set**&#x20;
{% endhint %}

#### **Bitwise XOR (^)**

* A bitwise XOR (exclusive or) performs an XOR operation between each bit between two numbers

```cpp
uint8_t a = 10;    // 0000 1010
uint8_t b = 30;    // 0001 1110
uint8_t c = a ^ b; // 0001 0100  (This is 20)
```

{% hint style="info" %}
**Bonus**: What is a result of a number XOR'd against itself?
{% endhint %}

### Bit-shift Operators&#x20;

#### Bitwise Right Shift (>>)

* A bitwise right shift (`>>`) move the entire bit sequence of a value to the right.&#x20;

```cpp
uint8_t a = 10;      // 0000 1010 
uint8_t b = a >> 1;  // 0000 0101  (All bits are shifted right)

uint8_t c = 15;      // 0000 1111
uint8_t d = c >> 2;  // 0000 0011  (Any extra bits are truncated)
```

#### Bitwise Left Shift (<<)

* A bitwise left shift (`<<`) moves the entire bit sequence of a value to the left.&#x20;

```cpp
uint8_t a = 10;      // 0000 1010 
uint8_t b = a << 1;  // 0001 0100  (All bits are shifted left)

uint8_t c = 150;      // 1001 0110
uint8_t d = c << 1;   // 0010 1100  (Any extra bits are truncated)
```

## Compound Assignment Operators

* Compound assignment operators modify the value of the left-hand operand by performing an operation on it.&#x20;

| Operator                       | Usage     | Equivalence  |
| ------------------------------ | --------- | ------------ |
| Addition assignment            | `x += y`  | `x = x + y`  |
| Subtraction assignment         | `x -= y`  | `x = x - y`  |
| Multiplication assignment      | `x *= y`  | `x = x * y`  |
| Division assignment            | `x /= y`  | `x = x / y`  |
| Modulo assignment              | `x %= y`  | `x = x % y`  |
| Bitwise left-shift assignment  | `x <<= y` | `x = x << y` |
| Bitwise right-shift assignment | `x >>= y` | `x = x >> y` |
| Bitwise AND assignment         | `x &= y`  | `x = x & y`  |
| Bitwise OR assignment          | `x \|= y` | `x = x \| y` |
| Bitwise XOR assignment         | `x ^= y`  | `x = x ^ y`  |

## Getting the Memory Occupied by a Variable

* The `sizeof` operator gives us the memory consumed, **in bytes**, by a particular type or variable&#x20;
* This is useful for determining how much memory to allocate for a **dynamic array**. (The memory occupied by a single element, multiplied by the number of elements)

## Operator Precedence&#x20;

* You might be familiar with **PEMDAS** or **BODMAS** (both are equivalent) from school, C++ **roughly** follows the same convention. (Note that there isn't an *exponent* or *order* operator in C++)

| Name                             | Operator      |
| -------------------------------- | ------------- |
| Parenthesis / Brackets           | `()`          |
| Multiplication, Division, Modulo | `*`, `/`, `%` |
| Addition, Subtraction            | `+`, `-`      |

* In the event that two operators of the same precedence appear in the same statement, they are evaluated from **left to right**.

```cpp
int a = 10 * 6 / 12;
```

* In the above example, since multiplication and division operators share the same precedence, `10 * 6` is first evaluated, then `60 / 12`, which gives us the result `5`.

{% hint style="danger" %}
For the most part, you do not need to memorise operator precedence outside of the above table. In situations of **any** ambiguity, you should **always use brackets** to disambiguate the order of operations.
{% endhint %}
