Previous Lecture lect05 Next Lecture

lect05, Tue 01/22

Functions, print vs. return, Memory Stack

Review - Control Structures: Loops

Remember to initialize your variables

While Loops

General syntax of a while loop:

while (BOOLEAN_EXPRESSION) {
	// code
	// ...
}
  1. Check if the BOOLEAN_EXPRESSION is true.
    • If true, the statements in loop will execute.
      • at the end of the loop, go back to while.
    • If false, the statements in the loop will not execute.
      • the program execution after the loop continues.

Example

int i = 0;
while (i < 10)
{
	cout << "i = " << i << endl;
	// add i++ afterwards to eliminate an infinite loop.
	// i++ → i = i + 1;
	// Remember to enclose this statement with { }
}

Do-while Loops

do {
	// code
	// ...
} while (BOOLEAN_EXPRESSION);
  1. Execute the code in the loop
  2. Check if BOOLEAN_EXPRESSION is true.
    • If true, then go back to do.
    • If false, then exit the loop and resume program execution.

Example

int i = 0;
do {
	cout << "i = " << i << endl;
	i++;
} while (i < 0);

For Loop

General syntax of a for loop:

for (INITIALIZATION; BOOLEAN_EXPRESSION; UPDATE) {
	// code
	// ...
}
  1. Execute the INITIALIZATION statement.
  2. Check if BOOLEAN_EXPRESSION is true.
    • if true, execute code in the loop block.
      • execute UPDATE statement.
      • Go back to the BOOLEAN_EXPRESSION.
    • if false, do not execute code in the loop.
      • exit the loop and resume program execution.

Example

for (int i = 0; i < 10; i++) {
	cout << “i = “ << i << endl;
}

Nested Loops

Other loops within a loop can be defined.

Example

for (int i = 0; i < 5; i++) {
	cout << “—“ << endl;
	cout << “i = “ << i << endl;
	for (int j = 0; j < 5; j++) {
		cout << “j = “ << j << endl;
	}
}

Continue and break statements

Example

for (int i = 0; i < 10; i++) {
	if (i == 4)
		continue;
	if (i == 7)
		break;
	cout << “i = “ << i << endl;
}

Precedence Rules

Highest precedence (done first)

    The unary operators +, -, ++, --, and !
    The binary arithmetic *, /, %
    The binary arithmetic +, -
    The Boolean operations <, >, <=, >=
    The Boolean operations ==, !=
    The Boolean operations &&
    The Boolean operations ||

Lowest precedence (done last)

C++ first evaluates the leftmost of the two expressions joined by an && or an ||. If that gives enough information to determine the final value of the expression (independent of the value of the second expression), then C++ does not bother to evaluate the second expression. This is called short-circuit evaluation. (Savitch, p.114-115)

Formatting output to the terminal

cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(2); // prints two decimal spaces for floating point values.

Example: A number guessing game

#include <iostream>

using namespace std;

const int ANSWER = 42; // const values cannot be modified

int main(int argc, char *argv[]) {

	int input = 0;

	do {
        cout << "Enter a negative number to stop playing." << endl;
		cout << "Guess a number between [0 - 100]: ";
		cin >> input;
		if (input == -1) { // sentinel value
			break;
        }
		if (input < ANSWER) {
			cout << "Too small" << endl;
			continue;
		}
		if (input > ANSWER) {
			cout << "Too big" << endl;
			continue;
		}
		if (input == ANSWER) {
			cout << "WINNER! ANSWER = " << ANSWER << endl;
			break;
		}
	} while (true);

	cout << "Thanks for playing!" << endl;
}

Note that the value -1 above is used as a sentinel value: one that is distinct from the possible input values being read in and so can be used as a signal to indicate the end of the list. (See Savitch, p. 158)

User Input

Example of using command line arguments

int main(int argc, char *argv[]) {
// cline.cpp
#include <iostream>
#include <cstdlib>

using namespace std;

int main(int argc, char *argv[]) {

	cout << "Number of arguments: " << argc << endl;

	cout << argv[0] << endl;
	cout << argv[1] << endl;
	cout << argv[2] << endl;

	// how to use these arguments as numbers?
	// We can convert them using the atoi function
	// in the cstdlib standard library

	int x = atoi(argv[1]) + atoi(argv[2]);
	cout << x << endl;
	return 0;
}

As you can see, the program expects three input arguments to the program:

    ./cline 1 2 3

If you don’t provide the correct number of arguments, you will get a segmentation fault, since the computer will be accessing the uninitialized parts of the memory. It is always best to check that the provided number of arguments matches what the program expects. Here’s the updated version of the above code:

#include <iostream>
#include <cstdlib>

using namespace std;

int main(int argc, char *argv[]) {
    int num_args = 4;

	cout << "Number of arguments: " << argc << endl;
	if (argc == num_args)
	{
		cout << argv[0] << endl;
		cout << argv[1] << endl;
		cout << argv[2] << endl;
		// how to use these arguments as numbers?
		// We can convert them using the atoi function
		// in the cstdlib standard library

		int x = atoi(argv[1]) + atoi(argv[2]);
		cout << x << endl;
	}
	else
	{
		//cout << "You need to provide 3 arguments after the name of the program.\n";
        // Subtract one to eliminate the first argument, which is the name of the program
		cout << "You need to provide " << (num_args - 1) << " arguments after the name of the program.\n";
	}
	return 0;
}

Functions

Function Declarations

In C++, a function declaration must occur BEFORE they are used. * We can write the method after it is used, we just need to declare it. * Declaration must include: [return type] [function name] (input parameters) * Basically just the header of the function (its “signature”), followed by a semicolon * It is possible to leave out a function declaration, if you can place the entire function definition (the body) before the main(), but this is not common because it is often impractical to bury the main() function at the end of a file.

Example: Simple Function Definition

#include <iostream>

using namespace std;

int areaOfSquare(int length); // declaration

int main() {
	int result = areaOfSquare(20); // call
	cout << result << endl;
	return 0;
}

int areaOfSquare(int length) { // definition
	return length * length;
}
// OK. Function declaration happens before it was used

-----------
#include <iostream>

using namespace std;

int main() {
	int result = areaOfSquare(20); // call
	cout << result << endl;
	return 0;
}

int areaOfSquare(int length) { // definition
	return length * length;
}
// ERROR! use of undeclared identifier 'areaOfSquare'

Return vs. Print

Example of printing, but not returning

void printAreaOfSquare(int area) {
	cout << “Area of Square: “ << area << endl;
	return; // return not necessary, will exit function when reached.
}

Memory Stack

Example

#include <iostream>

using namespace std;

int doubleValue(int x) {
	return 2 * x;
}

int quadrupleValue(int x) {
	return doubleValue(x) + doubleValue(x);
}

int main() {
	int result = quadrupleValue(4);
	cout << result << endl;
	return 0;
}
|                       |
|-----------------------|
| int main()            |
|_______________________|
|                       |
|-----------------------|
| int quadrupleValue(4) |
|-----------------------|
| int main()            |
|_______________________|
|                       |
|-----------------------|
| int doubleValue(4)         |
|-----------------------|
| int quadrupleValue(4) |
|-----------------------|
| int main()            |
|_______________________|
|                       |
|-----------------------|
| int quadrupleValue(4) |
|-----------------------|
| int main()            |
|_______________________|
|                       |
|-----------------------|
| int doubleValue(4)         |
|-----------------------|
| int quadrupleValue(4) |
|-----------------------|
| int main()            |
|_______________________|
|                       |
|-----------------------|
| int quadrupleValue(4) |
|-----------------------|
| int main()            |
|_______________________|
|                       |
|-----------------------|
| int main()            |
|_______________________|