Browse Source

day 2 plans

master
junikimm717 3 years ago
parent
commit
a5195b6dc0
  1. 2
      day1/Makefile
  2. 186
      day2/README.md
  3. 0
      lab/Main.cpp
  4. 2
      lab/Makefile

2
day1/Makefile

@ -1,2 +0,0 @@
CXX=g++-10
CXXFLAGS=-std=c++11 -O2 -Wall -Wextra -D_GLIBCXX_DEBIG -fsanitize=address -fsanitize=undefined

186
day2/README.md

@ -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
day1/Main.cpp → lab/Main.cpp

2
lab/Makefile

@ -0,0 +1,2 @@
CXX=g++-10
CXXFLAGS=-std=c++11 -O2 -Wall -Wextra -Wshadow -D_GLIBCXX_DEBIG -fsanitize=address -fsanitize=undefined
Loading…
Cancel
Save