|
3 years ago | |
---|---|---|
.. | ||
README.md | 3 years ago |
README.md
Operators
WIthin basic programming, there are a couple of operators that are almost universal amongst all C-like programming languages. These are the following:
- + (adding)
- - (subtraction)
- * (multiplication)
- / (division)
- % (modulo)
- && (and)
- || (or)
- ! (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++:
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:
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:
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:
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:
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:
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:
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:
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:
// 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:
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.