180 likes | 204 Views
Arrays and Pointers. Reference: Chapter 4.1-4.8, 4.11. Array A data type that groups many related data items of the same type for easy processing A complex (aggregate, composite) data type A homogeneous data type Elements occupy contiguous memory locations Pointer
E N D
Arrays and Pointers Reference: Chapter 4.1-4.8, 4.11
Array • A data type that groups many related data items of the • same type for easy processing • A complex (aggregate, composite) data type • A homogeneous data type • Elements occupy contiguous memory locations • Pointer • A value that points to the location (contains the address of) • another value • A simple data type • Typically stored as four bytes • Arrays and pointers have a very intimate relationship in C++.
Array Declaration and Initialization • Sample Declarations int x[5]; // 5 integer elements float z[16]; // 16 float elements char str[20]; // 20 character elements char* c[16]; // 16 character pointer elements • Sample Initializations int x[5] = {2, -8, 0, 10, 29}; // all elements initialized int y[] = {2, -8, 0, 10, 29}; // space automatically allocated float z[16] = {2.5, 8.9}; // remaining elements = 0.0 char str[20] = “Hello”; // str[5] = ‘\0’
Pointer Declaration and Initialization • Sample Declarations int* xPtr; // integer pointer char* chPtr; // character pointer Vector* vPtr; // Vector object pointer • Sample Initializations int x; int* xPtr = &x; // contains address of (points to) integer x char ch = ‘$’; char* chPtr = &ch; // points to character ch Vector v; Vector* vPtr = &v; // points to object v
Relationship Between Arrays and Pointers • An array name used with a subscript refers to a • particular element • int x[10]; • cout << x[8]; // displays contents of 9th element • An array name used without a subscript refers to the • address of the first element of the array • int x[10;] • cout << x; // displays the address of x[0] • Therefore, in this example, x is the same as &x[0]. • Note that x cannot be used as an lvalue.
Pointer Operations • Assignment • Pointers of the same type can be assigned to one another • Pointers of different types can be assigned only with an explicit type cast • The NULL pointer (usually zero) can be assigned to a pointer of any type • Comparison • Pointers of the same type can be compared using the relational operators ==, !=, <, >, <=, and >=
Pointer Operations (continued) • Indirection (Dereferencing) • int x = 5; • int* xPtr = &x; • cout << x; // displays 5 • cout << &xPtr; // displays address of xPtr • cout << xPtr; // displays value of xPtr (address of x) • cout << *xPtr; // displays 5 (value of x) • int** xPtrPtr = &xPtr; // double indirection • cout << &xPtrPtr; // displays address of xPtrPtr • cout << xPtrPtr; // displays value of xPtrPtr (address of xPtr) • cout << *xPtrPtr; // displays value of xPtr (address of x) • cout << **xPtrPtr; // displays 5 (value of x)
Pointer Operations (continued) • Pointer (Address) Arithmetic • pointer + integer • int* x; // assume 4-byte integer • char ch; // assume 1-byte char • x+=3; // increments x by 4*3=12 bytes • ch+=5; // increments ch by 1*5=5 bytes • pointer - integer • Analogous to pointer + integer • pointer - pointer • double *a, *b; // assume 8-byte double • x = b - a; // x is the integer difference between b and a • // in memory
Pointer Operations (continued) • Indexing • A pointer p, whether an array name or a pointer variable, can be • subscripted. • char p[10]; char* p; • p[3] = ‘a’; p[3] = ‘a’; // same as *(p+3) • Be careful! In the second case, you may be overwriting memory • that you shouldn’t be!
Passing Pointer Arguments • Example int strcmp(const char *r, const char *x) { // notice const while (*r == *s) { // dereferencing if (*r == ‘\0’) // dereferencing return(0); r++; s++; // pointer arithmetic } return(*r - *s); // dereferencing } Note that the function header could have been int strcmp(const char r[], const char x[])
Functions Returning Pointers • A function may return a pointer to a data type • Example • char* strcpy(char *s, const char *cs) { // notice const • char* tmp = s; • while (*cs != ‘\0’) • *(tmp++) = *(cs++); // copy the character • *tmp = ‘\0’; // don’t forget null terminator! • return(s); // returns a pointer to the string copied to • } • Calling strcpy: • char str1[20], str2[10] = “CMSC 202”; • cout << strcpy(str1, str2); // make sure str1 is big enough!
Pointers and Dynamically Allocated Storage • The declaration of an array is static int x[100]; // x always has 100 elements, even if // not all are needed • An array can be dimensioned dynamically by the use of a pointer to the array and the new operator int* x = new int[someInt]; // someInt = integer expression Here, the array will only be as large as is needed (no “guestimating” the maximum size needed). • Example - next slide
Pointers and Dynamically Allocated Storage (Continued) class Person { // static implementation public: Person(); void setLastName(char []); void setfirstName(char []); char* getLastName(); char* getFirstName(); private: char lastName[20]; // last name cannot exceed 20 characters char firstName[15]; // first name cannot exceed 15 characters }; Person p1, p2; // These objects will have the size of their last and // first names limited to 20 and 15, respectively
Pointers and Dynamically Allocated Storage (Continued) // static implementation Person::Person() { lastName[0] = ‘\0’; firstName[0] = ‘\0’; } void Person::setLastName(char last[]) { strcpy(lastName, last); // Last must be able to fit into lastName! } // Error check would be appropriate. void Person::setFirstName(char first[]) { strcpy(firstName, first]; // first must be able to fit into firstName! } char* Person::getLastName() {return(lastName);} char* Person::getFirstName() {return(firstName);}
Pointers and Dynamically Allocated Storage (Continued) class Person { // dynamic implementation public: Person(); void setLastName(char *); // note: could still use char[] void setfirstName(char *); char* getLastName(); char* getFirstName(); private: char* lastName; // Storage for first and last names will be char* firstName; // allocated dynamically }; Person p1, p2; // These objects can have first and last names of // different sizes
Pointers and Dynamically Allocated Storage (Continued) // dynamic implementation Person::Person() { lastName = firstName = NULL; // set name pointers to NULL } void Person::setLastName(char last[]) { // dynamic allocation lastName = new char [strlen(last) + 1]; strcpy(lastName, last); } void Person::setFirstName(char first[]) { // dynamic allocation firstName = new char[strlen(first) + 1]; strcpy(firstName, first); } char* Person::getLastName() {return(lastName);} // no change char* Person::getFirstName() {return(firstName);} // no change
Arrays of Pointers • Using arrays of pointers can save storage space • Example • typedef char Str10[10]; // define a string type of length 10 • Str10 daysOfWeek[7]; // array to hold names of days of week • strcpy(daysOfWeek[0], “Sunday”); • strcpy(daysOfWeek[6], “Saturday”); • Storage is wasted on days of the week that are less • than 9 characters in length. (“Wednesday” is the longest • with 9 characters.)
Arrays of Pointers (continued) • Using an array of pointers will save space • char* daysOfWeek[7]; • daysOfWeek[0] = new char[strlen(“Sunday”)+1]; • strcpy(daysOfWeek[0], “Sunday”); • daysOfWeek[0] = new char[strlen(“Saturday”)+1]; • strcpy(daysOfWeek[0], “Saturday”); • Notice that the strings in the array can be of different lengths, • thereby wasting no storage space.