lecture 01c: c++ review topics: static arrays array / pointer connection dynamic arrays (and...
TRANSCRIPT
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.
• All "normal" variables are "destroyed" when control leaves their scope.– This includes statically allocated arrays.
int main(){int x;float sizes[4];
cin >> x;if (x > 10){
double x; // Note: "name-masking"// …
}}
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
Examplefstream 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) // Note: NULL = 0 = false delete [] data;
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; // No brackets*single_double = 9.3;cout << *single_double << endl;delete single_double; // 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
• Static array, declared + initializedfloat 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 initializedfloat 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) cout << endl;else cout << " ";
}
delete [] dynamic_flat;