Preprocessors
- Preprocessor commands, which begins with
#, performs some actions before the complier does the translation.- The
includecommand is to include a header file:- Files containing definitions of common variables and functions.
- Written to be included by other programs.
#include <iostream>: Before the compilation, the complier looks for theiostreamheader file and copy the codes therein to replace this line.- We may define our own variables and functions into self-defined header files and include them by ourselves:
#include "myHeader"- Use double quotation marks instead of angle brackets.
- A path must be specified.
- The
Namespaces
-
Suppose all roads in Taiwan have different names. In this case, we do not need to include the city/county name in our address.
-
This is why we do not need to specify the district for an address in the Taipei city.
-
But we need to specify the district for an address in the New Taipei County.
-
A C++ namespace is a collection (space) of names.
- For C++ variables, functions, object, etc.
- The objects
cout,cin, and all other items defined in the C++ standard library are defined in the namespacestd.
-
By writing
using namespace std;, whenever the complier sees a name, it searchs whether it is defined in this program or the namespacestd. -
The scope resolution operator (
::)- We may specify the namespace of
couteach time when we use it with the scope resolution operation::
- We may specify the namespace of
#include <iostream>
int main()
{
std::cout << "Hello World!\n" << std::endl; // \a std::
return 0;
}
Selection
- The
ifstatement
if (condition)
{
statements
}
- The
if-elsestatement
if (condition)
{
statements1
}
else
{
statement2
}
- Example
int income = 0, tax = 0;
cout << "Please enter your income: ";
cin >> income;
if (income <= 10000)
{
tax = 0.02 * 10000;
}
else
{
tax = 0.08 * (income - 10000) + 200;
}
- An
ifor anif-elsestatement can be nested in anifblock or/andelseblock.
#include <iostream>
using namespace std;
int main()
{
int a = 0, b = 0, c = 0;
cout << "Enter three numbers: ";
cin >> a >> b >> c;
if (a <= b)
{
if (a <= c)
{
cout << a << " is the smallest\n";
}
else
{
cout << c << " is the smallest\n";
}
}
else
{
if (b <= c)
{
cout << b << " is the smallest\n";
}
else
{
cout << c << " is the smallest\n";
}
}
}
- Revised version:
#include <iostream>
using namespace std;
int main()
{
int a = 0, b = 0, c = 0;
cout << "Enter three numbers: ";
cin >> a >> b >> c;
int min = c;
if (a <= b)
{
if (a <= c)
{
min = a;
}
}
else
{
if (b <= c)
{
min = b;
}
}
cout << min << " is the smallest";
}
-
The ternary
ifoperator? : -
In many cases, what to do after an
if-elseselection is simple. -
The ternary
ifoperator? :can be helpful in this case. -
condition ? operation A : opertion B;: ifconditionis true, dooperation A; otherwise,operation B. -
Second revised version:
#include <iostream>
using namespace std;
int main()
{
int a = 0, b = 0, c = 0;
cout << "Enter three numbers: ";
cin >> a >> b >> c;
int min = c;
if (a <= b)
a < c ? min = a : min = c;
else
min = b <= c ? b : c;
cout << "The smallest number is " << min << endl;
}
-
Ternary
ifoperators can also be nested (but not suggested) -
min = a <= b ? a <= c? a : c : b <= c ? b : c; -
min = (a <= b ? (a <= c? a : c) : (b <= c ? b : c)); -
Dangling
if-else- What does this mean?
if (a == 10)
if (b == 10)
cout << "a and b are both ten. \n";
else
cout << "a is not ten. \n";
- In the current C++ standard, it is actually:
if (a == 10)
{
if (b == 10)
cout << "a and b are both ten. \n";
else
cout << "a is not ten. \n";
}
-
When we drop
{}, our programs may be grammatically ambiguous. -
In the field of Programming Languages, it is called the dangling program.
-
To handle this, C++ defines that “one
elsewill be paired to the closestifthat has not been paired with anelse.” -
Good programming style:
- Drop
{ }only when you know what you are doing. - Align your
{ }. - Indent your codes properly.
- Drop
-
Logical operators
&&: and.||: or.!: not.- These operators have their aliases (
and,or, andnot).
-
Each of the two conditions must be complete by itself.
if (a >= 10 && <= 20) // error! \a
cout << "a is between 10 and 20";
- Two conditions can be combined only with a logical operator.
if (10 <= a <= 20) // error! \a
cout << "a is between 10 and 20";
- Associativity and precedence
- The
&&and||operators both associate the two conditions from left to right. - It is possible that the second condition is not evaluated at all.
- If evaluating the first one is enough.
- There is a precedence rule for operators.
- Use parentheses.
- The
#include <iostream>
using namespace std;
int main()
{
int a = 0, b = 0;
if ((a > 10) && (b = 1))
;
cout << b << endl; // result: 0 \a
if ((a > 10) || (b = 5))
;
cout << b << endl; // result: 5 \a
}
switch-case
switch (operation)
{
case value 1:
statements
break;
case value 2:
statements
break;
...
default:
statements
break;
}
- it is particularly useful for responding to multiple values of a single operation.
- For the operatoion:
- It can contain only a single operand.
- It must return an integer.
- After each
case, there is a value. - If the returned value of the operation equals that value, those statements in the case block will be executed.
- No curly brackets are needed for blocks.
- A colon is needed after the value.
- A
breakmarks the end of a block.- The
breakof the last section is optional.
- The
- Restriction on those values:
- Cannot be (non-constant) variables.
- Must be different integers.
- What will happen if we enter 10?
int a;
cin >> a;
switch (a)
{
case 10:
cout << "ten";
case 6:
cout << "six";
break
}
-
Example:
-
Given a year and a month, how many days is in that month?
-
There are four possibilities:
- 31 days: January, March, May, July, August, October, December.
- 30 days: April, June, September, November.
- 29 days: Februray in a leap year.
- 28 days: Februray in a ordinary year.
-
A year is a leap year if:
- It is a multiple of 400, or
- It is a multiple of 4 but not a multiple of 100.
-
Version 1
#include <iostream>
using namespace std;
int main()
{
int year = 0, month = 0;
cout << "Enter year and month: ";
cin >> year >> month;
int days = 0;
if (month ==1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12)
days = 31;
else if (month == 4 || month == 6 || month == 9 || month == 11)
days = 30;
else if ((year % 400 == 0) || (year % 4 == 0 && year % 100 != 0))
days = 29;
else
days = 28;
cout << "Number of days: " << days << endl;
}
- Version 2
#include <iostream>
using namespace std;
int main()
{
int year = 0, month = 0;
cout << "Enter year and month: ";
cin >> year >> month;
int days = 0;
switch (month)
{
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
days = 31;
break;
case 4: case 6: case 9: case 11:
days = 30;
break;
case 2:
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
days = 29;
else
days = 28;
}
cout << "Number of days: " << days << endl;
}
Repetition
whileanddo-while
while (operation)
{
statements
}
do
{
statements
} while (operation); // semicolon \a
-
loop counter
-
Using the unary increment/decrement operator
++/--can be more convenient.(NOTE: postfix/prefix?) -
Binary self-assigning operators (e.g.,
+=). -
For modifying
i,i++has the same effect asi = i + 1. -
For modifying
i,i--has the same effect asi = i -1. -
They can be applied on all basic data types.
- But we should only apply them on integers.
- Typically, using them is faster than using the corresponding addition/subtraction and assignment operation.
-
Both can be put at the left or the right of the operand.
- This changes the order of related operations.
i++: returns the value ofi, and then incrementi.++i: incrementsi, and then returns the incremented value ofi.- So is
i = i + 1equivalent toi++or++i? (ans:++i)
-
Self-assigning operations
- Typically
a += bis ** ** thana = a + b, etc.
- Typically
-
for
for (init; condition; some)
{
statements
}

-
You need those two
;in the( ). -
The typical way of using a for statement is:
init: Initialize a counter variable.cond: Set up the condition on the counter variable for the loop to continue.some: Modify (mostly increment or decrement) the counter variable.statements: The things that we really want to do.
-
Multi-counter
forloops- Inside one
forstatement:- You may initialize multiple counters at the same time.
- You may also check multiple counters at the same time.
- You may also modify multiple counters at the same time.
- Use
&&or||to connect operations on multiple counters.
- Inside one
for (int i = 0, j = 0; i < 10 && j > -5; i++, j--)
cout << i << " " << j << endl;
-
Good programming style:
- When you need to execute a loop for a fixed number of iterations, use a
forstatement with a counter declared only for the loop- This also applies if you know the maximum number of iterations.
- This avoids poetential conflicts on variable names.
- Use the loop that makes your program the most readable.
- Typically only the counter variable enters the
()of aforstatement. - You may use fractional numbers for a counters, but this not recommended.
- Use integer only.
- Drop
{}only when you know what you are doing. - Align your
{}. Indent your codes properly.
- When you need to execute a loop for a fixed number of iterations, use a
-
Scope of variable
- variables live only in the block in which they are declared.
- Two variables declared in the same level cannot have the same name.
int i = 0;
for (; i< 10; i++)
cout << i << endl;
// ...
int i = 0; // error! \a
for (; i < 10; i++)
cout << i << endl;
- This is a good reasons to use
for: All loops at the same level may use the same name for loop counters.
for (int i = 0; i< 10; i++)
cout << i << endl;
// ...
for (int i = 0; i < 10; i++)
cout << i << endl;
- However, a variable of an existing name is allowed to be declared in an inner block.
- In the inner block, after the same variable name is used to declare a new variable, it “replace” the original one.
- However, its life ends when the inner block ends.
int a = 0;
if (a == 0)
{
cout << a << endl;
int a = 10;
cout << a << endl;
}
cout << a << endl;
breakandcontinue- When we implement a repetition process, sometimes we need to further change the flow of execution of the loop
- A
breakstatement brings us to exit the loop immediately. - When
continueis executed, statements after it in the loop are skipped.- The looping condition will be checked immediately.
- If it is satisfied, the loop starts from the beginning again.
- How to write a program to print out all integers from 1 to 100 except multiples of 10.
for (int a = 1; a <= 100; a++)
{
if (a % 10 != 0)
cout << a << endl;
}
for (int a = 1; a <= 100; a++)
{
if (a % 10 == 0)
continue;
cout << a << endl;
}
- The effect of
breakandcontinueis just on the current level.- If a
breakis used in an inner loop, the execution jumps to the outer loop - If a
continueis used in an inner loop, the execution jumps to the condition check of the inner loop.
- If a
- What will be printed out at the end of this program
#include <iostream>
int main()
{
using namespace std;
int a = 0, b = 0;
while (a <= 10)
{
while (b <= 10)
{
if (b == 5)
break;
cout << a * b << endl; // result: a = 0, b = 0: 0, 0, 0, 0, 0; a = 1, b = 5:
b++;
}
a++;
}
cout << a << endl; // result: 11
return 0;
}
- Using
breakgives a loop multiple exits- It becomes harder to track the flow of a program.
- It becomes harder to know the state after a loop
- Using
continuehighlights the need of getting to the next iteration.- Having too many continue still gets people confused.
- Be careful not to hurt the readability of a program too much.