200 likes | 334 Views
Homework due. Test the random number generator Create a 1D array of n ints Fill the array with random numbers between 0 and 100 Compute and report the average of the array contents Do this for n = 10, 100, 1000, 10000, 100000. Homework due. Create a 2D array of m x n ints
E N D
Homework due • Test the random number generator • Create a 1D array of n ints • Fill the array with random numbers between 0 and 100 • Compute and report the average of the array contents • Do this for n = 10, 100, 1000, 10000, 100000
Homework due • Create a 2D array of m x n ints • Fill the array with random numbers between 0 and 100 • Compute and report the average of the array contents • Do this for all combinations of m = {1, 10, 100} and n = {1, 10, 100, 1000}
Homework – special instructions • Do not use any hard coded values or constants when calculating loop indices • Use the techniques discussed for computing the number of elements in rows/columns of an array • Due Thursday, next class meeting – I’ll look at your results in class
C++ Arrays – Part II
Run time allocation • Allocate an array of 20 ints int array[20]; • Allocates an array of 20 elements in main memory at compile time • But what if we don’t know how big the array should be when we are compiling the program? • Java has no issues with this since everything is run time allocate
Run time allocation • The dreaded “P” word…Pointers! • In C++ a pointer is nothing more than a variable that holds an address in memory • Whereas most variables are themselves addresses in memory and hold data • It’s often referred to as an indirect address
x 10 y 20 z 30 a[0] 0 a[1] 0 a[2] 0 “Regular” (non-pointer) variables int x = 10; int y = 20; int z = 30; int a[3] = {0};
px py pz pa Pointer variables int *px; int *py; int *pz; int *pa; ? • Notes • int* x; is the same as int *x; • int* x, y; declares 1 pointer (*x) and 1 non-pointer (y) variable
x 10 y 20 z 30 a[0] 0 a[1] 0 a[2] 0 Pointers – what do you do with them? int *px; int *py; int *pz; int *pa; int x = 10; int y = 20; int z = 30; int a[3] = {0}; px = &x; py = &y; pz = &z; pa = a; px x py y pz z pa a • You can use them to refer to (point to) other variables • The & is called the “address-of” operator and returns the address of the variable it is operating on • Note that the array name is already and address and needs no &
Pointing to other variables • These assignments will change the contents of the variables to whom they point • x is now 27 • y is now 28 • x is now 29 • a now holds {30, 31, 32} • The * is called the “indirection” operator and refers to the contents of the variable it is operating on • Note that the array index operators [ and ] perform a similar task on array type variables *px = 27; *py = 28; *pz = 29; pa[0] = 30; pa[1] = 31; pa[2] = 32;
Why? • Typically, you won’t use pointers to access individual (primitive) variables • You might use pointers to access arrays • At one point in time it used to be faster to do so rather than use indexing – not clear if this is still true • You could use an array of pointers to create a “ragged edged” array (like you can do in Java) • The real value of pointers is in dynamic, run time memory allocation
Array access though pointers int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} for (int i = 0; i < 10; ++i) { std::cout << a[i] << std::endl; } int *pa = a; for (int i = 0; i < 10; ++i) { std::cout << *pa << std::endl; ++pa; } • The tricks • Pointer arithmetic (like ++pa) is smart enough to know how much to add to the pointer (address) to get to the next variable of the appropriate type • e.g. if pointing to an int it adds 4, if pointing to a char it adds 1, if pointing to a double it adds 8 • Similar for things like pa += 2 (adds 8 for an int, 2 for a char, 16 for a double) • Be sure to initialize the pointer properly • Know how far you can go before overrunning the end of the array
Dynamic memory allocation • It’s really quite simple int x = 5; int *pa = new int[x]; for (int i = 0; i < x; ++i) { *(pa + i) = i; } delete [] pa; • Note that you have to keep track of the size – sizeof(pa) / sizeof(pa[0]) will not work
What not to do int x = 5; int *pa = new int[x]; for (int i = 0; i < x; ++i) { *pa = i; ++pa; } delete [] pa; • Why is this a very, very, very bad thing to do?
To fix it int x = 5; int *pa = new int[x]; for (int i = 0; i < x; ++i) { *(pa + i) = i; } delete [] pa;
Dynamic multi-dimensional arrays • Basically, you need to dynamically allocate an array of pointers • The method shown in the book is (in my opinion) hooky at best • Here’s how I do it…
Dynamic multi-dimensional arrays int rows = 4; int cols = 5; // -- requires a pointer to a pointer int **ma; // -- requires two separate allocations // and some pointer assignments ma = new int*[rows]; ma[0] = new int[rows * cols]; for (int i = 1; i < rows; ++i) { ma[i] = ma[i - 1] + cols; }
Dynamic multi-dimensional arrays // -- now you can access it as a normal 2D array for (int i = 0; i < rows; ++i) { for (int j = 0; j < cols; ++j) { ma[i][j] = i * cols + j; } } for (int i = 0; i < rows; ++i) { for (int j = 0; j < cols; ++j) { std::cout << ma[i][j] << "\t"; } std::cout << std::endl; }
Dynamic multi-dimensional arrays // -- you have to delete both allocations in // reverse order delete [] ma[0]; delete [] ma;
Homework • Same as the last assignment but this time use dynamically allocated arrays and ask the user how big they should be • i.e. you only need to write and compile 2 programs, 1 for the 1D case and 1 for the 2D case • All the different run sizes will be handled at run time based on user inputs • Due next class period