450 likes | 472 Views
Learn about static and dynamic arrays in C++, their declaration, manipulation, and best practices for efficient programming. Understand array initialization, passing arrays as parameters, indexing, and memory management. Enhance your programming skills today!
E N D
Advanced Program Design with C++ Static arrays Dynamic arrays Joey Paquet, 2007-2016
Arrays • Array definition: • A collection of data elements of same type • Identified by a sequential index • Simple aggregate data type • Can create arrays of elements of any type • Used for lists of related items • Test scores, temperatures, names, etc. • Avoids declaring multiple simple variables • Can be manipulated as a single entity, with some restrictions Joey Paquet, 2007-2016
Declaring an array • Declaring an array allocates memory on the stack: int score[5]; • Declares array of 5 integers named "score" • Similar to declaring five variables: int score[0], score[1], score[2], score[3], score[4] • Individual parts are often called using different terms: • Indexed or subscripted variables • Elementsof the array • Value in brackets called index or subscript • Numbered from [0] to [size – 1] Joey Paquet, 2007-2016
Accessing an array • Access using index/subscript cout << score[3]; • Note two different uses of brackets: • In declaration, specifies the size of the array • Anywhere else, specifies an index • Size and subscript need not be literal int score[MAX_SCORES]; score[n+1] = 99; • If n is 2, identical to: score[3] • However, the size needs to be a constant expression • A constant expression is an expression that is composed of only constant components. • Why? The compiler needs to know what is the size of the array in order to allocate memory to it at compile time. • Subscript can be any expression eventually evaluating to an integer value (constant or not) Joey Paquet, 2007-2016
Simple program using an array Joey Paquet, 2007-2016
Simple program using an array Joey Paquet, 2007-2016
Arrays and loops • Arrays and loops • Loop constructs naturally works well for "counting through" elements of an array • Example: for (intidx= 0; idx<5; idx++) {cout << score[idx] << "off by " << max – score[idx] << endl; } • Loop control variable idxcounts from 0 to 4 Joey Paquet, 2007-2016
Index range • Valid range: • Start with zero • Zero is the first number in natural numbers • Index is used to compute offset of value in the array • End with size -1 • C++ will let you go beyond range • Unpredictable results • Compiler will not detect these errors! • In many cases, execution will continue as if nothing wrong happened • Up to programmer to stay in range • Major source of bugs • A major feature in the toolbox of malicious programmers… Joey Paquet, 2007-2016
Use of constant as size • Always use defined/named constant for array size • Example:const int NUMBER_OF_STUDENTS = 5; int score[NUMBER_OF_STUDENTS]; • Improves readability • Improves versatility • Improves maintainability Joey Paquet, 2007-2016
Use of constant as size • Use everywhere size of array is needed • In for-loop for traversal:for (idx = 0; idx < NUMBER_OF_STUDENTS; idx++){ // Manipulate array} • In calculations involving size:lastIndex = (NUMBER_OF_STUDENTS – 1); • When passing array to functions (later) • If size changes requires only one change in program (and recompilation) • If not, need to track required changes in many places, which is very error-prone. Joey Paquet, 2007-2016
Arrays in memory • Array are stored as a contiguous block of memory. • Arrays are implicitly managed using pointers and pointer arithmetics. Given: int a[3]; int b; • The elements of a are of type int. • However, a itself is implicitly a pointer that points to the first element of a. • Given an index, the compiler calculates an address offset that now points to the proper array element. • It will not check whether this points outside of the array. Joey Paquet, 2007-2016
Array initialization • As simple variables can be initialized at declaration:int price1 = 0; int price2 {0}; • Arrays can be initialized as well:intchildren[3] = {2, 12, 1}; • Equivalent to following:intchildren[3]; children[0] = 2; children[1] = 12; children[2] = 1; • If the number of elements in the initialization list is greater than the size of the array, it generates a compile-time error. • If the number of elements in the initialization list is lesser than the size of the array, all missing elements are initialized to 0. • If the size is not specified, the size is assumed to be equal to the number of elements in the initialization list. Joey Paquet, 2007-2016
Passing arrays as parameters • Arrays can be passed as parameters to functions. • In order to compile and do processing on an array in functions receiving an array as parameter, three things are needed: • Address of array: to generate offsets during compilation of the code to refer to the proper addresses where each array element resides. • Array base type: for type checking during compilation. • Size of array: To know how many elements there are in the array, e.g. to implement a loop over the entire array. • Syntax allows to pass an array as a parameter: intmyfunc(int p[]); • However, what is really happening if you use that, is that only a pointer to p is passed as value. • myfunc operates on the original array • myfunc is not aware of the size of the array passed Joey Paquet, 2007-2016
Returning an array • Functions cannot return arrays in the same way simple types are returned. • Requires use of a pointer. • The reason behind this is the same reason as for passing arrays as pointers: efficiency. • Passing an array as value, or returning an array from a function, or having array assignment would assume that arrays are copied as they are passed around and manipulated, leading to increased memory consumption and execution time. • C/C++ are designed for efficiency. Joey Paquet, 2007-2016
example: partially filled arrays Joey Paquet, 2007-2016
Example: partially filled arrays Joey Paquet, 2007-2016
Example: partially filled arrays Joey Paquet, 2007-2016
Example: partially filled arrays Joey Paquet, 2007-2016
Example: partially filled arrays Joey Paquet, 2007-2016
Example: partially filled arrays Joey Paquet, 2007-2016
example: searching in a partially-filled array Joey Paquet, 2007-2016
Example: searching in a partially-filled array Joey Paquet, 2007-2016
Example: searching in a partially-filled array Joey Paquet, 2007-2016
Example: searching in a partially-filled array Joey Paquet, 2007-2016
Example: searching in a partially-filled array Joey Paquet, 2007-2016
example: selection sort Joey Paquet, 2007-2016
Example: selection sort Joey Paquet, 2007-2016
Example: selection sort Joey Paquet, 2007-2016
Example: selection sort Joey Paquet, 2007-2016
Example: selection sort Joey Paquet, 2007-2016
Example: selection sort Joey Paquet, 2007-2016
Multidimensional arrays • Arrays with more than one index • char page[30][100]; • Two indexes: An "array of arrays" • Visualize as:page[0][0], page[0][1], …, page[0][99]page[1][0], page[1][1], …, page[1][99]…page[29][0], page[29][1], …, page[29][99] • C++ allows any number of indexes Joey Paquet, 2007-2016
Multidimensional arrays • A one-dimensional array is stored as a pointer to an array of data elements. • A two-dimensional array is stored as a pointer to an array of arrays of data elements. • And so on and so forth… int a[3][4]; Joey Paquet, 2007-2016
Passing multidimensional arrays as a parameter • Similar to one-dimensional array • 1st dimension size not given • Provided as second parameter • 2nd dimension, and succeeding size is given though • Why? • The compiler needs to know the sizes of the dimensions in order to calculate the offsets, as each row is of a fixed size specified by the number of elements in the array. • This restriction greatly limits the usefulness of static multidimensional arrays as parameters. • Example:void displayPage(const char p[][100], int sizeDimension1) { for (int index1=0; index1<sizeDimension1; index1++) { for (int index2=0; index2 < 100; index2++) cout << p[index1][index2]; cout << endl; } } Joey Paquet, 2007-2016
Multidimensional arrays • As the array is also stored in contiguous memory space, pointer arithmetic can still be used. • However, each row needs to be entirely skipped if referring to an element of further rows. Joey Paquet, 2007-2016
Multidimensional arrays Joey Paquet, 2007-2016
dynamically allocated arrays Joey Paquet, 2007-2016
Dynamically allocated arrays • Static array limitations • Must specify size first • May not know until program runs. • Very limited in its application. • May use partially filled arrays for more flexibility • Must estimate maximum size needed • Wastes memory • Dynamic arrays • Can grow and shrink as needed • Implemented as a pointer to a dynamically allocated static array. Joey Paquet, 2007-2016
Initializing a dynamically allocated array • Use newoperator • Create a pointer variable to the base type of the array elements. • Dynamically allocate an array using new. • Make the pointer variable point to the newly allocated array. • Then treat just like a standard array. • If size needs to be changed, just create a new one of different size, and copy the elements into the newly created one. • Example:double *d; d = new double[10]; • Creates dynamically allocated array variable d, with ten elements of base type double. • Stored using the same model as a static array, except that the arrays of elements is stored on the heap instead of the stack, and thus each need to be pointed to by a pointer, thus it requires arrays of pointers. Joey Paquet, 2007-2016
Deallocating a dynamically allocated array • Allocated dynamically at run-time. • So should be destroyed explicitly at run-time. double *d; d = new double[10]; … //Processing delete [] d; • delete [] de-allocates all memory for a dynamic array • Brackets indicate array is pointed to • Recall: d still points there! • Should set d = NULL; • How does it know the size of what was pointed to? • When you call new double[10], the run-time system actually stores the size of the array that it is allocating. • It then uses this information when you call delete [] d Joey Paquet, 2007-2016
Multidimensional dynamically allocated array • Can also be done by explicitly creating a nested array using pointers similar to a static array. • For example, to create an 3x4 array of integers: • First, create the array of 3 pointers that will eventually point to the 3 arrays of 4 integers, create a pointer variable that points to it (which is thus a pointer to a pointer to an int): int** a = new int*[3]; • Then use a loop to allocate 3 arrays of integers and have the pointers point to them: for (inti = 0; i < 3; i++) a[i] = new int[4]; • Results in three-by-four dynamic array • Same structure as an equivalent static array, except that it is allocated on the heap, and uses additional pointers. Joey Paquet, 2007-2016
Multidimensional dynamically allocated array • Results in three-by-four dynamic array • Not same structure as an equivalent static array: • Requires an additional pointer redirection level for each additional dimension. • Allocated on the heap, which cannot be assumed to be allocated contiguously. • Hence, the same simple pointer arithmetic does not apply. Joey Paquet, 2007-2016
Multidimensional dynamically allocated array • As it was dynamically allocated, it then needs to be explicitly deallocated. • Each sub-array element has to be explicitly deallocated: • First, delete the arrays of integers: for (inti = 0; i < 3; i++)delete [] a[i]; • Then delete the array of pointers: delete [] a; • One more embedded for loop for each additional dimension. • Tedious and careful memory management is required. Joey Paquet, 2007-2016
Other solutions • The Boost library also has an array class that implements a simple class embedding a static array and that stores its own size, making it much more practical than C++ basic static arrays. • Some say that one should always use STL containers such as vector instead of dynamically allocated arrays. • These are less error-prone than basic C++ arrays, as they provide features such as bounds checking and embed memory allocation/deallocation mechanisms. • A vector allows automatic resizing of the array if necessary. • However, such features come with a certain cost: • Additional data is required to manage the container’s mechanism. • Computation time is required to manage the container’s mechanism. • In many cases, the overhead is negligible. • More on STL containers later. Joey Paquet, 2007-2016
References • Y. Daniel Liang, Introduction to Programming with C++ (Chapter 7, 11), Peason, 2014, ISBN-13: 978-0133252811. • Walter Savitch, Absolute C++ (Chapter 5, 7, 10, 19), Addison-Wesley, 2005, ISBN-13: 9780321330239. • Bjarne Stroustrup, The C++ Programming Language (Chapter 6, 7, 11), Addison-Wesley, 2013, ISBN-13: 978-0321563842 Joey Paquet, 2007-2016