Lecture 9
Lecture 9
Programming
Steve James
Lecture 9
References
• “Reference” is a general concept
int i = 0; int i = 0;
int r = i; int &r = i;
r = 9; //i still 0! r = 9; //i becomes 9 also!
int main(){
int myVar = 0;
cout << "In main, the address of myVar is " << &myVar << endl;
f(myVar);
cout << "Value of myVar is " << myVar << endl;
g(myVar);
cout << "Value of myVar is " << myVar << endl;
return 0;
myVar in main x in f
}
/*
In main, the address of myVar is 0x7ffca4514414
In f, the address of x is 0x7ffca45143fc
Value of myVar is 0
In g, the address of x is 0x7ffca4514414
Value of myVar is 1
*/
Pass by reference vs value
#include <iostream>
When we call g
using namespace std;
int main(){
int myVar = 0;
cout << "In main, the address of myVar is " << &myVar << endl;
f(myVar);
x in g
cout << "Value of myVar is " << myVar << endl;
g(myVar);
cout << "Value of myVar is " << myVar << endl;
return 0;
myVar in main
}
/*
In main, the address of myVar is 0x7ffca4514414
In f, the address of x is 0x7ffca45143fc
Value of myVar is 0
In g, the address of x is 0x7ffca4514414
Value of myVar is 1
*/
Early Abstraction
SCOPE
Scope
• Refers to visibility, accessibility and lifetime of
objects, functions
string name;
void greet(){
cout << "Hello " << name << endl;
}
int number;
int main(){
number = 2;
name = "Bob";
greet();
return 0;
}
int main(){
int x;
cin >> x;
if (x > 0){
}
else{
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>
int main(){
{ //scope block
int p;
}
{
int x;
{ //nested block
int y; //both x, y exist here
}
//only x exists here
}
C++11
Recall Lists
• Python lists
– Store collection of values (of any type)
• C++ equivalents:
– Arrays (fixed-size) and vectors (variable size)
– Must be same (homogeneous) type
– Both arrays and vectors are STL classes
C++11 Arrays
• Need to know the size before program runs!
• Requires C++11
• An array is a contiguous group of memory
locations that all have the same type
• To refer to a particular element in the array,
specify the name of the array and the index of
the particular element
Arrays: Example
d is an int array
d [0] 43 of size 9
d [1] -6
d [2] 55
d [3] 12 The position number is
d [4] 0
d [5] 99 more formally called
d [6] -3 the index or subscript.
d [7] 42
d [8] 99
A subscript must be an
integer (or integer
expression)
Declaring Arrays
• Arrays occupy space in memory
• Specify type and number of elements required
by an array using:
array<type, arraySize> arrayName;
• e.g array<int, 9> d;
• Compiler reserves appropriate amount of
memory based on type and size of array
Arrays in Practice
#include <iostream>
#include <array>
using namespace std;
integral type. /*
Output:
Recommended
Element Value
when referring 0 0
to size of array 1 0
2 0
3 0
4 0
*/
Arrays in Practice
#include <iostream>
#include <array>
using namespace std;
int main(){
myArr = [1, 2, 3, 4, 5]
Specifying the size
• The array size must be a constant expression
– The compiler must be able to prove the value
✓
• Literals:
array<int, 5> d;
• Variables:
✘
size_t N;
cin >> N;
array<int, N> d;
✘
• Variables:
size_t N = 5;
array<int, N> d;
✓
• Constant expression:
constexpr size_t N = 5;
array<int, N> d;
• C++ provides no automatic array bounds checking to prevent
you from referring to an element that does not exist.
• Thus, an executing program can “walk off” either end of an
array without warning.
• It’s important to ensure that every subscript you use to access
an array element is within the array’s bounds – that is,
greater than or equal to 0 and less than the number of array
elements.
• Allowing programs to read from or write to array elements
outside the bounds of arrays are common security flaws.
• Reading from out-of-bounds array elements can cause a
program to crash or even appear to execute correctly while
using bad data.
• Writing to an out-of-bounds element (known as a buffer
overflow) can corrupt a program’s data in memory, crash a
program and allow attackers to exploit the system and
execute their own code.
• Referring to an element outside the array bounds is an
execution-time logic error. It is not syntax error.
Indexing Issues
• [] operator does not perform any checks
• Attempting to access out-of-bounds index is
undefined behaviour
#include <iostream> #include <iostream>
#include <array> #include <array>
“Inusing
general,namespace
whenever youstd;
encounter undefinedusing
behaviour, anything might
namespace std; happen.
The application
int main(){ may crash, it may freeze, it may int
eject your CD-ROM drive or make
main(){
demons array<int,
come out of your0>nose.
a; It may format your harddrive
array<int, 1> a;
cout << a[0] << endl; cout << a[2] << endl;
It may
} even, if you are really unlucky, appear to } work correctly.”
-Jesper Alf
Segmentation fault (core dumped) 0
Safer Access
• Use at function
– Performs a check before accessing element
– So it’s slower, but provides predictable behaviour
#include <iostream> #include <iostream>
#include <array> #include <array>
using namespace std; using namespace std;
int main(){ int main(){
array<int, 0> a; array<int, 1> a;
cout << a.at(0) << cout << a.at(2) <<
endl; endl;
} }
terminate called after throwing an terminate called after throwing an
instance of ‘std::out_of_range’ instance of ‘std::out_of_range’
myArr = [1, 2, 3, 4, 5]
for val in myArr:
print(val)
Range-based for loop
• The type must be consistent with the array
type
• The identifier represents successive array
element values on successive iterations
• Can use this kind of loop on most STL data
structures (containers)
– array and vector
#include <iostream>
#include <array>
#include <cstdlib>
int main(){
array<int, 5> d = {1, 2, -1, 3, 5};
cout << "Items before modification: " << endl;
for (int item : d){
cout << item << " ";
}
//multiple elements of d by 3
for (int &itemRef : d){
itemRef *= 3;
}
cout << endl << "Items after modification: " << endl;
for (int item : d){
cout << item << " ";
}
cout << endl;
return 0;
}
/*
Items before modification:
1 2 -1 3 5
Items after modification:
3 6 -3 9 15
*/
Range-based for loop
• Use int reference because d contain int values and we
want to modify each element’s value
• Because itemRef is declared as a reference, any change
you make to itemRef changes the corresponding element
value in the array.
• The range-based for statement can be used in place of the
counter-controlled for statement whenever looping
through an array does not require access to the
element’s subscript.
• However, if a program must use subscripts for some reason
other than simply to loop through an array (e.g., to print
a subscript number next to each array element value),
you should use the counter-controlled for statement.
Summary: Iterating over arrays
for (size_t i = 0; i < arr.size(); ++i){
cout << i << ":\t" << arr[i] << endl;
}