junikimm717
4 years ago
4 changed files with 188 additions and 2 deletions
-
2day1/Makefile
-
186day2/README.md
-
0lab/Main.cpp
-
2lab/Makefile
@ -1,2 +0,0 @@ |
|||||
CXX=g++-10 |
|
||||
CXXFLAGS=-std=c++11 -O2 -Wall -Wextra -D_GLIBCXX_DEBIG -fsanitize=address -fsanitize=undefined |
|
@ -0,0 +1,186 @@ |
|||||
|
# Operators |
||||
|
|
||||
|
WIthin basic programming, there are a couple of operators that are almost |
||||
|
universal amongst all C-like programming languages. These are the following: |
||||
|
|
||||
|
1. \+ (adding) |
||||
|
2. \- (subtraction) |
||||
|
3. \* (multiplication) |
||||
|
4. \/ (division) |
||||
|
5. \% (modulo) |
||||
|
6. && (and) |
||||
|
7. || (or) |
||||
|
8. \! (not) |
||||
|
|
||||
|
Think of these operators as being ways by which you can mutate the state of |
||||
|
the program to reflect how much information you have at the moment. |
||||
|
|
||||
|
# Conditional flow |
||||
|
|
||||
|
If statements have the following syntax in C++: |
||||
|
|
||||
|
```cpp |
||||
|
if (condition) { |
||||
|
// resulting code |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
Usually, the condition is a boolean statement that you pass in that evaluates to |
||||
|
true or false. However, you will find that if you write the following: |
||||
|
|
||||
|
```cpp |
||||
|
if (1) { |
||||
|
//code |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
The inside code will always run. This is because non-null and non-zero values |
||||
|
get evaluated to true by default (this is convenient as a shortcut at times) |
||||
|
while nulls and zeroes are false. |
||||
|
|
||||
|
Conditionals are often used to handle edge cases in a program or a base case |
||||
|
in recursion, in which you execute those extra steps only if the desired case |
||||
|
applies. |
||||
|
|
||||
|
# Looping |
||||
|
|
||||
|
## For loop |
||||
|
|
||||
|
There are two different syntaxes in a for loop. The first is as follows: |
||||
|
|
||||
|
```cpp |
||||
|
for (int i = 0; i < (number); ++i) |
||||
|
``` |
||||
|
|
||||
|
(the second is a for-each loop, which we will get to once we talk about |
||||
|
sets and maps) |
||||
|
|
||||
|
Inside this for loop, the variable i will be brought to scope, from which |
||||
|
you can use it in whatever way you wish. |
||||
|
|
||||
|
This is particularly useful for when you need a sequence of numbers that |
||||
|
represent indices of an array (from 0 to N-1) or when there are a certain |
||||
|
number of test cases. |
||||
|
|
||||
|
### Warning (Variable Shadowing) |
||||
|
|
||||
|
There are many instances when programmers tend to write the following when |
||||
|
writing nested for loops: |
||||
|
|
||||
|
```cpp |
||||
|
for (int i = 0; i < N; ++i) { |
||||
|
for (int i = 0; i < M; ++i) { |
||||
|
// code |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
Since the inner i has the same name as the outermost i, it *shadows* the |
||||
|
other value, leading to behavior that is incredibly difficult to debug. |
||||
|
In order to warn us when we do such things, we add the -Wshadow flag in |
||||
|
our build command. |
||||
|
|
||||
|
For the above, you probably want to do this instead: |
||||
|
|
||||
|
```cpp |
||||
|
for (int i = 0; i < N; ++i) { |
||||
|
for (int j = 0; j < M; ++j) { |
||||
|
// code |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
This prevents the inner and outer for loop variables from shadowing |
||||
|
each other. |
||||
|
|
||||
|
## While loop |
||||
|
The while loop syntax is as follows: |
||||
|
|
||||
|
```cpp |
||||
|
while (condition) { |
||||
|
//code |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
Although a for loop will be used far more often than a while loop, it is |
||||
|
important to still understand its semantics. A while loop will check |
||||
|
**at the beginning of each iteration** as to whether or not its condition |
||||
|
is true, and will terminate the loop if its condition is false. |
||||
|
|
||||
|
|
||||
|
# Termination statements |
||||
|
|
||||
|
Sometimes, you need a way to exit a loop, an individual loop iteration, or |
||||
|
possibly an entire program if certain constraints apply. |
||||
|
|
||||
|
For instance, you might want to check for a very trivial case in a program, |
||||
|
in which you can do the following: |
||||
|
|
||||
|
```cpp |
||||
|
if (trivial_case) { |
||||
|
cout << endl; |
||||
|
return 0; |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
Within this code, we are flushing all of the output we have to the console, |
||||
|
and then returning with an error code. 0 indicates no error, while positive |
||||
|
integers correspond with specific types of errors. |
||||
|
|
||||
|
In a loop, if you wish to terminate the current iteration of the loop, you can |
||||
|
do the following: |
||||
|
|
||||
|
```cpp |
||||
|
for (loop statement) { |
||||
|
// code block 1 |
||||
|
if (condition) { |
||||
|
continue; |
||||
|
} |
||||
|
// code block 2 |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
If the statement is true in a certain iteration, then code block 1 will be |
||||
|
executed, but code block 2 will not, as the continue directive immediately |
||||
|
sends the execution of the program to the next iteration. |
||||
|
|
||||
|
This is useful if, for instance, you have an array of integers, some of which |
||||
|
you need to do a very trivial manipulation on. You can then use the continue |
||||
|
statement to go to the next iteration once this manipulation is done. This is |
||||
|
better in contrast to writing a bunch of nested if/else statements and makes |
||||
|
your code slightly more neat. |
||||
|
|
||||
|
The **break** statement will terminate a loop entirely. For instance, let's |
||||
|
say you are implementing a program that uses a simple linear search to find |
||||
|
the first element in an array that satisfies a certain constraint. We could |
||||
|
do the following: |
||||
|
|
||||
|
```cpp |
||||
|
// arr is a vector. |
||||
|
int ans = arr.size(); |
||||
|
for (int i = 0; i < arr.size(); ++i) { |
||||
|
if (arr[i] satisfies a constraint) { |
||||
|
ans = i; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
In this case, we want to use the **break** statement, as we have now found our |
||||
|
answer. |
||||
|
|
||||
|
Of course, it is possible to eliminate the break statement altogether |
||||
|
by running the for loop backwards: |
||||
|
|
||||
|
```cpp |
||||
|
int ans = arr.size(); |
||||
|
for (int i = (int) arr.size()-1; i >= 0; --i) { |
||||
|
if (arr[i] satisfies a constraint) { |
||||
|
ans = i; |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
As we go from last to the first index, ans will be updated to the index that is |
||||
|
closest to the front. This goes to show you that you should be thinking heavily |
||||
|
not just about when you have for loops, but in what **direction** they should go. |
@ -0,0 +1,2 @@ |
|||||
|
CXX=g++-10 |
||||
|
CXXFLAGS=-std=c++11 -O2 -Wall -Wextra -Wshadow -D_GLIBCXX_DEBIG -fsanitize=address -fsanitize=undefined |
Write
Preview
Loading…
Cancel
Save
Reference in new issue