Lecture01c_cpp_review

Lecture 01c: C++ review
Topics:
• static arrays
• array / pointer connection
• dynamic arrays (and pointers)
• 2D arrays
Overview
• Arrays are a group of contiguous,
homogeneous data.
– We can get around both restrictions with [our
own] data structures
• Two types:
– statically allocated (the "easier" kind): we know at
compile time how many elements will be in the
array.
– dynamically allocated: we don't
• Example: reading an image from disk => memory
PartI: Static arrays
double enemyDistances[6]; // Use const int or macros?
Enemy enemies[6];
// A user-defined class
enemyDistances[0] = 15.7;
enemyDistances[1] = enemyDistance[2] * 2;
cout << enemyDistances[3] << endl; // output?
cout << enemyDistances << endl;
// output?
Scope
• We'll talk more about this after functions…
• Basically scope defines:
– where a particular name is valid
– when that name "dies"
• C/C++ use block scope
Scope, cont.
int main()
{
int x;
float sizes[4];
cin >> x;
if (x > 10)
{
double x;
// …
}
}
// Note: "name-masking"
• All "normal" variables are "destroyed" when
control leaves their scope.
– This includes statically allocated arrays.
Part II: Arrays and pointers
• [Look at the memory diagram for last
example].
• Now add…
double enemyDistances[6]; // Use const int or macros?
double d;
double * p;
enemyDistances[0] = 15.7;
p = &d;
*p = 17.6;
p = &enemyDistances[5];
*p = 9.1;
p = enemyDistances;
*p = 3.3;
// Error?
cout << p << endl;
cout << sizeof(double) << endl;
cout << p + 2 << endl;
*(p + 2) = 11.2;
p[2] = 11.2;
// Exactly the same!
Part III: Dynamic allocation
• Some differences
– Memory allocation is from the heap; "normal"
allocation (static) is from the stack.
– The memory stays allocated until we free it
• No automatic cleanup when we leave the scope.
• OK…the compiler / OS probably clean up after the program
ends, but…
– It must be done through pointers.
• Note: there are two (slightly different) syntaxes:
– array allocation
– single allocation
Example
fstream fp;
int width, height;
char * data = NULL;
fp.open("my_img.jpg", ios::in | ios::binary);
fp.seekg(8, ios_base::beg);
// I'm fudging jpeg format...
fp.read((char*)&width, 4);
// Note the (C-style) cast
fp.read((char*)&height, 4);
fp.seekg(4, ios_base::cur);
data = new char[width * height];
fp.read(data, width * height);
// No cast needed
fp.close();
// ... Use data ...
// De-allocate data
if (data)
delete [] data;
// Note: NULL = 0 = false
Dynamic allocation (of singular types)
• Note: you can allocate a single item on the
heap
– not super useful for "standard" types
– Very useful for objects
• The syntax is a bit different
double * single_double = NULL;
single_double = new double;
*single_double = 9.3;
cout << *single_double << endl;
delete single_double;
// No brackets
// No brackets
Part IV: 2D arrays
• A "normal" array (dynamic and static) are like
a 1-dimensional array.
• You can also represent 2 (or higher)
dimensional data
• Two options:
– Create a "flat" array and convert row/col numbers
to an offset.
– Let the compiler generate these offsets for you.
Examples
• Let's say we want to store this data
4.0 −6.3 2.1
1.9 0.0 −5.8
• Static array, declared + initialized
float static_arr[2][3] = {{4.0f, -6.3f, 2.1f},
{1.9f, 0.0f, -5.8f}};
for (i=0; i<2; i++)
{
for (j=0; j<3; j++)
cout << static_arr[i][j] << " ";
cout << endl;
}
Static array, declared, then initialized
float static_arr2[2][3];
static_arr2[0][0] = 4.0f;
static_arr2[0][1] = -6.3f;
static_arr2[0][2] = 2.1f;
static_arr2[1][0] = 1.9f;
static_arr2[1][1] = 0.0f;
static_arr2[1][2] = -5.8f;
Examples, cont.
• dynamically allocated [Show memory diagram]
float ** dynamic_array;
dynamic_array = new float*[2];
dynamic_array[0] = new float[3];
dynamic_array[1] = new float[3];
dynamic_array[0][0] = 4.0f;
dynamic_array[0][1] = -6.3f;
dynamic_array[0][2] = 2.1f;
dynamic_array[1][0] = 1.9f;
dynamic_array[1][1] = 0.0f;
dynamic_array[1][2] = -5.8f;
// Use the same way as the static array before
delete [] dynamic_array[0];
delete [] dynamic_array[1];
delete [] dynamic_array;
Examples, cont.
• Dynamically allocated "flat" array
float * dynamic_flat = NULL;
int i;
dynamic_flat = new float[2 * 3];
dynamic_flat[0 * 3 + 0] = 4.0f;
dynamic_flat[0 * 3 + 1] = -6.3f;
dynamic_flat[0 * 3 + 2] = 2.1f;
dynamic_flat[1 * 3 + 0] = 1.9f;
dynamic_flat[1 * 3 + 1] = 0.0f;
dynamic_flat[1 * 3 + 2] = -5.8f;
for (i=0; i < 3 * 2; i++)
{
cout << dyamic_flat[i];
if (i > 0 && i % 3 == 0)
else
}
delete [] dynamic_flat;
cout << endl;
cout << " ";