Introduction to Algorithms &
Programming
Steve James
Lecture 8
Recap
• Made the switch from Python to C++
• Last lecture covered variables, if-statement, loops
• Upcoming assignment:
– Friday, 11 April
• Upcoming test:
– COMS1018A: 10 April, 14h15 in MSL
– COMS1022A: 9 April, 17h30 in MSL
General Form
• Python
if <exp>:
# do something
else:
# do something else
Must have round brackets
• C++ Curly brackets, not colon
and indentation
if (<exp>){
// do something
}
else{
//do something else
}
While Loop General Form
• Python
while <exp>:
# statement 1
# statement 2
• C++ Must have round brackets Curly brackets, not colon
and indentation
while (<exp>){
// statement 1
// statement 2
}
For Loop General Form
• Python
for i in range(start, stop, step):
# statement 1
# statement 2
• C++ Initialisation Termination Update
for (int i = start; i < stop; i = i + step){
// statement 1
// statement 2
}
C++
FUNCTIONS
2 𝑓 𝑥 =
𝑓 𝑥 =𝑥
𝑥2
𝑠𝑞𝑢𝑎𝑟𝑒 𝑛𝑢𝑚 = 𝑠𝑞𝑢𝑎𝑟𝑒 𝑥 =
𝑛𝑢𝑚2 𝑥2
𝑠𝑞𝑢𝑎𝑟𝑒 𝑛𝑢𝑚 {
𝑛𝑢𝑚2
}
double 𝑠𝑞𝑢𝑎𝑟𝑒 double 𝑛𝑢𝑚 {
return 𝑛𝑢𝑚 ∗ 𝑛𝑢𝑚;
}
General Form
• Python
def <function_name>(<params>):
# function body
Curly brackets, not colon
Must specify return type
and indentation
• C++
<return_type> <functionName>(<params>){
// function body
}
Examples
int main(){ How to call the functions:
cout << "Hello, world" << endl;
return 0;
}
double pow(double x, double y){
double x = 5;
return __builtin_powl(x, y);
} double y = pow(2, x);
void greet(){
cout << "Hello!" << endl; greet();
}
void greet(string name, int numTimes){
for (int i = 0; i < numTimes; ++i){
cout << “Hello ” << name << endl; greet("Bob", 10);
}
}
Properties of functions
• The function definitions and the main routine
can be put into the same file (or different files)
• Functions must be declared before they are
used
• Functions may return at most one thing via
the return statement Type must match return type in function header
• The parameters in the function definition
must be declared. e.g. (double x, int y)
• Variables passed to function are unaffected
Properties of functions
• Once the function returns, the variables in the
parameter list and any other variables that it
declares are lost.
• Functions can call other functions.
• main is just another function.
• If function does not return anything, it’s type is
void
• If a function has no input parameters, leave
brackets empty e.g. int main()
Function Declarations
• Like variables, we can declare functions
without defining what they actually do
• Function declaration (prototype) specifies
return type, function name and parameter list
• Function prototype and definition must agree
Function Declarations
#include <iostream> #include <iostream>
using namespace std; using namespace std;
int main(){ void showMessage(int, int); //function prototype
int m, n;
cin >> m >> n;
showMessage(m, n); int main(){
return 0; int m, n;
} cin >> m >> n;
showMessage(m, n);
void showMessage(int x, int y){ return 0;
for (int i =0; i < x; ++i){ }
for (int j =0; j < y; ++j){
cout << "*"; void showMessage(int x, int y){
} for (int i =0; i < x; ++i){
cout << endl; for (int j =0; j < y; ++j){
} cout << "*";
} }
cout << endl;
/* }
decl1.cpp: In function int main(): }
decl1.cpp:7:18: error: showMessage was not declared in
this scope
showMessage(m, n);
*/
Function Return
• Functions can return in 3 ways
– Running into its closing bracket (for void
functions)
– Running into the statement return; (for void
functions)
– Running into the statement return <exp>;
• non-void functions must return like this
• <exp> should be the correct type
Examples
#include <iostream>
using namespace std;
//we run into the closing bracket and exit
void f(){
cout << "Hello, world!" << endl;
} //returns here
//early return from void function
void g(double x, double y){
if (y == 0){
cout << "y can't be 0" << endl;
return; //returns here
}
cout << "Calculating..." << endl;
double z = (x * x + y * y)/y;
cout << "The answer is " << z << endl;
}
//return from non-void
string h(string firstName, string surname){
if (firstName == "" || surname == ""){
return "Default Name"; //returns here
}
return firstName + " " + surname; //returns here
}
int main(){
return 0;
}
Function Declarations
• Like variables, we can declare functions
without defining what they actually do
• Function declaration (prototype) specifies
return type, function name and parameter list
• Function prototype and definition must agree
C++
PASS-BY-VALUE & REFERENCES
Pass-by-Value
#include <iostream>
using namespace std;
int increment(int x){
x = x + 1;
return x;
}
int main(){
int x = 0;
cout << increment(x) << endl; //prints 1
cout << x << endl; //prints 0; function didn't change x
int y = 7;
cout << increment(y) << endl; //prints 8
cout << y << endl; //prints 7; function didn't change y
return 0;
}
increment
main Copy the value
x:0
x:0
x:1
stack frame
stack frame
main increment
Copy the value x:7
x:0
y:7 x:8
Pass-by-Value
• The value of the arguments are passed to the
function
• The original variables are thus unaffected
• Such a function can only return one value
– What if we want more?
• Or, what if we actually want to modify the
original variables?
Variable Locations
• First, we need an understanding of variable
addresses
– where they are stored in the computer’s memory
• The operator & – called the address operator –
obtains the address of a variable
• e.g. double x;
&x The address of double x
Example
#include <iostream>
using namespace std;
int main(){
int x = 2; // Declare and initialize an int
float y = 5.0f; // Declare and initialize a float
double z = 7.0; // Declare and initialize a double
cout << "x’s value: " << x << " x’s address: " << &x << "\n";
cout << "y’s value: " << y << " y’s address: " << &y << "\n";
cout << "z’s value: " << z << " z’s address: " << &z << "\n";
cout << "size of x: " << sizeof(x) << " bytes" << "\n";
cout << "size of y: " << sizeof(y) << " bytes" << "\n";
cout << "size of z: " << sizeof(z) << " bytes" << "\n";
return 0;
}
/*
x’s value: 2 x’s address: 0x7fffda1837d0
y’s value: 5 y’s address: 0x7fffda1837d4
z’s value: 7 z’s address: 0x7fffda1837d8
size of x: 4 bytes
size of y: 4 bytes
size of z: 8 bytes
*/
#include <iostream>
using namespace std;
int square(int x) {
cout << "In function square(), x is located at " << &x << endl;
return (x * x);
}
int cube(int x) {
cout << "In function cube() , x is located at " << &x << endl;
return (x * x * x);
}
int main() {
int x = 2, squared, cubed;
cout << "In main():\n"
<< " x is located at " << &x << endl
<< " squared is located at " << &squared << endl
<< " cubed is located at " << &cubed << endl
<< "Before square() and cube() function calls:\n"
<< " x = " << x << endl
<< " squared = " << squared << endl
<< " cubed = " << cubed << endl;
squared = square(x);
cubed = cube(x);
cout << "After square() and cube() function calls:\n"
<< " x = " << x << endl
<< " squared = " << squared << endl
<< " cubed = " << cubed << endl; In main():
x is located at 0x7fffe865e6f4
return (0); squared is located at 0x7fffe865e6f8
} cubed is located at 0x7fffe865e6fc
Before square() and cube() function calls:
x = 2
squared = 0
cubed = 0
In function square(), x is located at 0x7fffe865e6dc
In function cube() , x is located at 0x7fffe865e6dc
After square() and cube() function calls:
x = 2
squared = 4
cubed = 8
Pass-By-Reference
• If we want to modify variable passed to
function
• Pass it by reference, not value:
void func(int param1,int ¶m2){
}
Pass-by value Pass-by reference
#include <iostream>
using namespace std;
void squareCube(int x, int &y, int &z) {
cout << "In function squareCube():\n"
x by value, y and z by reference
<< " x is located at " << &x << "\n"
<< " y is located at " << &y << "\n"
<< " z is located at " << &z << "\n";
y = x * x;
z = x * x * x;
}
int main() {
int x = 2, squared, cubed;
cout << "In main():\n"
<<
<<
" x is located at " << &x << endl
" squared is located at " << &squared << endl
y and z get the address of the
<<
<<
" cubed is located at " << &cubed << endl
"Before squareCube() function calls:\n" variables passed to the function
<< " x = " << x << endl
<< " squared = " << squared << endl
<< " cubed = " << cubed << endl;
squareCube(x, squared, cubed);
cout << "After squareCube() function call:\n"
<< " x = " << x << endl
<< " squared = " << squared << endl
<< " cubed = " << cubed << endl;
In main():
return (0);
x is located at 0x7fffc3f9cc44
} squared is located at 0x7fffc3f9cc48
cubed is located at 0x7fffc3f9cc4c
Before squareCube() function calls:
x = 2
squared = 0
cubed = 0
In function squareCube():
x is located at 0x7fffc3f9cc2c
y is located at 0x7fffc3f9cc48
z is located at 0x7fffc3f9cc4c
After squareCube() function call:
x = 2
squared = 4
cubed = 8
References
• “Reference” is a general concept
– Not just pass-by-reference
int i = 0;
int &r = i;
r = 9; //i becomes 9 also!
• Can think of a reference as an alternative
name for an object
Example
#include <iostream>
using namespace std;
void callByValue(int i, int j) {
i = i + 1;
j = j + 1;
}
void callByReference(int& i, int& j) {
i = i + 1;
j = j + 1;
}
int main(void) {
int m = 0, n = 0;
What is the output?
cout << "Before callByValue() function call:"
<< " m = " << m << ", n = " << n << "\n";
callByValue(m, n);
cout << "After callByValue() function call:"
<< " m = " << m << ", n = " << n << "\n";
callByReference(m, n);
cout << "After callByReference() function call:"
<< " m = " << m << ", n = " << n << "\n";
callByValue(m, n);
cout << "After callByValue() function call:"
<< " m = " << m << ", n = " << n << "\n";
callByReference(m, n);
cout << "After callByReference() function call:"
<< " m = " << m << ", n = " << n << "\n";
return 0;
}
Early Abstraction
SCOPE
Scope
• Refers to visibility, accessibility and lifetime of
objects, functions
• e.g. when can we use a variable or function?
• Depends on where declaration occurs
File Scope
• Identifier declared outside any function
definition has file scope
– “global variables”, function definitions/prototypes
outside other functions
• If program consists of multiple files, each has
no knowledge of file-scoped identifiers
outside itself
File Scope
#include <iostream>
using namespace std;
string name;
void greet(){
cout << "Hello " << name << endl;
}
int number;
int f(int x);
int main(){
number = 2;
name = "Bob";
greet();
return 0;
}
int f(int x){
return x * x;
}
Block Scope
• A block is anything within braces: { ... }
• Variables declared in a block only exist within
that block.
• Variables with block scope are known as local
variables
Block Scope
#include <iostream>
using namespace std;
void greet(string name){
cout << "Hello " << name << endl;
int main(){
int x;
cin >> x;
if (x > 0){
string s = "Cassper Nyovest";
greet(s);
}
else{
string s = "Big Zulu";
greet(s);
for (int i = 0; i < 10; ++i){
double q = i + 2;
cout << q << endl;
return 0;
}
Block Scope
• There are also nested blocks e.g. nested if-
statements/loops
• We can define our own blocks simply by using
{ ... } anywhere
• Variables carry into nested scope blocks
• Variable in inner block can have same name as
one in outer block
– Outer block variable will be hidden
Nested Scope
#include <iostream>
using namespace std;
int main(){
{ //scope block
int p;
}
//p does not exist here
{
int x;
{ //nested block
int y; //both x, y exist here
}
//only x exists here
}
for (int i =0; i < 10; ++i){
int outerScope = 10;
for (int j = 0; j < 10; ++j){
int outerScope = 5; //hides variable
cout << outerScope;
}
cout << endl;
}
return 0;
}