1 / 40

C++ Pointers and Arrays

C++ Pointers and Arrays. CSCD 326. Variable Attributes. Attributes of a “variable”: Contents - the value stored in the memory location(s) used for the variable Address - each byte of memory has a unique address which allows the CPU to access that memory location

warlene
Download Presentation

C++ Pointers and Arrays

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. C++ Pointers and Arrays CSCD 326

  2. Variable Attributes • Attributes of a “variable”: • Contents - the value stored in the memory location(s) used for the variable • Address - each byte of memory has a unique address which allows the CPU to access that memory location • Access to a named variable’s attributes: • variable name - a reference to the value of the variable • e.g. x = x + 3 • &variable name - a reference to the address at which the variable is stored • e.g. &x CSCD 326

  3. Pointers and Indirect References • Pointers are variables used to store the address of another memory location • Pointers provide indirect access to a value stored in memory • Using the address stored in a pointer to access a value stored in that address is called dereferencing the pointer Addresses Contents 10A0 Pointer 2000 2000 5 CSCD 326

  4. Address 1000 1004 1008 C++ Pointer syntax • Declaration of a pointer object (variable) int *Ptr; • this declares an object or variable called Ptr which can contain the address of an integer object • Pointer Assignment int X = 5; int Y = 7; Ptr = &Y; //&Y is the address of Y Name Contents Ptr 1008 7 X 5 Ptr Y Y 7 CSCD 326

  5. Address 1000 1004 1008 Dereferencing Operator • Allows access to the value of the data whose address is contained in a pointer for use in an expression or assignment • *Ptr evaluates to 7 • *Ptr = 15; -- assigns value 15 to the integer whose address is contained in Ptr • * is the opposite of & so: *(&X) is the same as X Name Contents Ptr 1008 15 X 5 Ptr Y Y 15 CSCD 326

  6. #include <iostream.h> #include <stdlib.h> void main() { int *ptr, i = 15; // assignment of addresses to a pointer variable ptr = NULL; ptr = (int *)0xfffe; ptr = &i; cout << "address of i: " << ptr << "\n"; cout << "contents of i: " << *ptr << "\n"; } Pointer Example CSCD 326

  7. Pointer Example Output address of i: 0x0012FF78 contents of i: 15 Press any key to continue CSCD 326

  8. Pointer expressions #include <stdlib.h> #include <iostream.h> void main() { int i = 3, j = 5, k; int *p = &i, *q = &j, *r; *(r = &k) = *p * *q; cout << "r: " << *r; } Output: r: 15 CSCD 326

  9. Pointer expressions memory i 3 j 5 k p &i q &j r CSCD 326

  10. SmallArray[0] SmallArray[1] SmallArray[2] SmallArray[3] SmallArray[4] Arrays and Pointers int SmallArray[] = {1,3,5,7,9}; int *Iptr; Iptr = SmallArray; Name Address 1000 1 SmallArray 1004 3 5 1000 1008 7 100C 9 1010 Iptr 1014 1000 CSCD 326

  11. SmallArray[0] SmallArray[1] SmallArray[2] SmallArray[3] SmallArray[4] Array address calculations • To determine the address of SmallArray[I]: • compiler calculates - SmallArray + (I * 4) • or 1000 + (I * 4) Name Address 1000 1 SmallArray 1004 3 5 1000 1008 7 100C 9 1010 Iptr 1014 1000 CSCD 326

  12. Pointer Arithmetic • Pointer arithmetic can be used in the same way as array notation to access array members • Recall from previous example: • Iptr = SmallArray; • the members of SmallArray can now be accessed as: • *(Iptr +1) *(Iptr +2)etc. • or as*(SmallArray + 1) *(SmallArray + 2) • Since both Iptr and SmallArray are pointers, these expressions are pointer arithmetic • *(Iptr + I) is evaluated as: • Iptr + (I * sizeof(*Iptr)) or Iptr + (I * 4) in this case • So - *(SmallArray + I) is the same as: SmallArray[I] CSCD 326

  13. Category Operator Associativity Overloadable Scoping ::(unary) ::(class) L to R No Postfix () [] -> . ++ -- L to R Yes, except . Prefix sizeof * & ! ~ + - ++ -- new delete R to L Yes, except sizeof Pointer Operators and precedence • Shown below is the top of the C++ precedence chart: • consider the following expressions: • int X[5], *Ptr = X; • *Ptr++ ++*Ptr ++X[0] Ptr++[0] • ++X[2] CSCD 326

  14. Strings • C++ has its own string type and can be accessed via the standard template library (STL). • More specifically, you #include <string> and follow it with the statement: using namespace std;. • The using namespace std; further requires that all other C++ header files are included without a .h. • Furthermore, old C style libraries are included by preceding the library name with a c (once again the .h is left off) • C type strings are still supported and we will use them- you may use your own user-defined string classes in programs CSCD 326

  15. C type Strings • C strings are arrays of characters in which the end of the string is indicated by a char containing 0 (character constant ‘\0’) • the string array must be large enough to accommodate the extra terminal character • C strings are of type char * or const char * char astr[7]; int i; OR astr[0] = ‘s’; *(astr) = ‘s’; astr[1] = ‘t’; *(astr + 1) = ‘t’; astr[2] = ‘r’; *(astr + 2) = ‘r’; astr[3] = ‘i’; *(astr + 3) = ‘i’; astr[4] = ‘n’; *(astr + 4) = ‘n’; astr[5] = ‘g’; *(astr + 5) = ‘g’; astr[6] = ‘\0’; *(astr + 6) = ‘\0’ CSCD 326

  16. C String Functions #include <string.h> char * strcpy(char *, const char *); char * strcat(char *, const char *); int strcmp(const char *, const char *); size_t strlen(const char *); • strcpy- copies characters from its second parameter to its first - returns the address of the string copied to • strcat - adds characters in second parameter to the end of the first CSCD 326

  17. C String Functions (cont) • strcmp- compares characters from second argument to those from first - return value indicates either equality or which string is larger • return value: • <0 - string1(first arg) less than string2 • 0 - the strings are identical • > 0 - string1 is greater than string2 • strlen - counts characters in its argument - up to but NOT including the terminal 0 and returns this count CSCD 326

  18. String Constants • Specified with quotes -- “string” • Placed into memory allocated by the compiler with the nul terminator added • thus “string” occupies 7 bytes of memory • Uses of string constants: • can be used anywhere both a string and a constant can - e.g. as the second (but not first) parameter to strcpy • as array initializers: char str[10] = “string”; here characters are copied from the constant to the array • assignment to pointers: char *mystr = “string”; here the address of the memory location of the constant is assigned to mystr CSCD 326

  19. Pointer Hopping #include <stdio.h> void strcpy1(char s[],char t[]); void strcpy2(char *s,char *t); void strcpy3(char *s,char *t); void strcpy4(char *s,char *t); void main(void) { char s1[50], *s2; s2 = "this is a literal string"; printf("s1: %s\ns2: %s\n",s1,s2); //cout << “s1:” << s1 << “\ns2: “ << s2 << “\n”; strcpy1(s1,s2); printf("s1: %s\ns2: %s\n",s1,s2); } CSCD 326

  20. Pointer Hopping (2) void strcpy1(char s[],char t[]) { int i; i = 0; while((s[i] = t[i]) != '\0') { s++; t++; } } void strcpy2(char *s, char *t) { while((*s = *t) != '\0') { s++; t++; } } CSCD 326

  21. Pointer Hopping (3) void strcpy3(char *s, char *t) { while((*s++ = *t++) != '\0') ; } void strcpy4(char *s, char *t) { while(*s++ = *t++) ; } CSCD 326

  22. Dynamic Memory Allocation • The new[ ] and delete [] operators can be used to allocate variable sized blocks of memory for classes, structures and arrays while a program is running • static allocation (at the start of a program or function) often requires too much memory to be allocated and wasted • example of dynamic array allocation char *str; str = new char[5]; // allocates 5 bytes Assert(str); strcpy(str, “test”); delete [ ] str; str = NULL; CSCD 326

  23. Memory Leaks • Happen any time memory allocated with new is not returned with delete • Scope related example: void F( int i ) { int A1[10]; int *A2 = new int [10]; … G(A1); G(A2); } • When scope is exited memory from automatic array A1 is freed but not memory pointed by A2 - 10 ints leak - delete [] A2 would fix CSCD 326

  24. Extending Arrays • The new and delete operators can be used to reallocate arrays during program execution to make them larger • the following program reads an infinite number of integers - until 0 is read - and stores them in an extensible array CSCD 326

  25. #include <iostream> #include <cstdlib> using namespace std; // Read an unlimited number of ints. // Return a pointer to the data, and set ItemsRead. int * GetInts( int & ItemsRead ) { int ArraySize = 0; int InputVal; int *Array = 0; // Initialize to NULL pointer ItemsRead = 0; cout << "Enter any number of integers: "; while( cin >> InputVal ) { if( ItemsRead == ArraySize ) { // Array Doubling Code int *Original = Array; Array = new int[ ArraySize * 2 + 1 ]; for( int i = 0; i < ArraySize; i++ ) Array[ i ] = Original[ i ]; delete [ ] Original; // Safe if Original is NULL ArraySize = ArraySize * 2 + 1; } Array[ ItemsRead++ ] = InputVal; } return Array; } CSCD 326

  26. #include <new> //allows us to handle memory exceptions using namespace std; main( ) { int *Array; int NumItems; // The actual code try { Array = GetInts( NumItems ); for( int i = 0; i < NumItems; i++ ) cout << Array[ i ] << '\n'; } catch( bad_alloc exception ) { cerr << "Out of memory!" << endl; exit( 1 ); } return 0; } CSCD 326

  27. Memory Exhaustion • A mechanism is needed to report when dynamically allocated memory (heap) is exhausted • C mechanism - new returns NULL pointer • C++ exception mechanism • VC++ 6.0 – must #include <new>, which allows new to throw a C++ exception of type bad_alloc in the event of an allocation failure • in your code, you can use try/catch exception handling constructs to detect and handle bad_alloc exceptions CSCD 326

  28. Reference Variables (& parameters) • A reference type is a pointer constant which is always dereferenced implicitly • example: int LongVariableName = 0; int & Cnt = LongVariableName; Cnt += 3; • reference variables must be initialized - they are constants • reference variable names are implicitly dereferenced unlike all other pointer types • example of reference types as parameters: CSCD 326

  29. Swap Functions #include <iostream.h> void SwapWrong( int A, int B ); void SwapPtr( int *A, int *B ); void SwapRef( int & A, int & B ); // Simple program to test various Swap routines main( ) { int X = 5; int Y = 7; SwapWrong( X, Y ); cout << "X=" << X << " Y=" << Y << '\n'; SwapPtr( &X, &Y ); cout << "X=" << X << " Y=" << Y << '\n'; SwapRef( X, Y ); cout << "X=" << X << " Y=" << Y << '\n'; return 0; } CSCD 326

  30. // Does not work void SwapWrong( int A, int B ) { int Tmp = A; A = B; B = Tmp; } // C Style -- using pointers void SwapPtr( int *A, int *B ) { int Tmp = *A; *A = *B; *B = Tmp; } // C++ style -- using references void SwapRef( int & A, int & B ) { int Tmp = A; A = B; B = Tmp; } CSCD 326

  31. 2D Arrays and Pointers (1) #include <stdio.h> void main(void) { int array[3][4],i,j,val=0; for(i=0;i < 3; i++) for(j=0; j < 4; j++) { array[i][j] = val++; printf("array[%d][%d]: %d\n",i,j,array[i][j]); } printf("array: %x\n",array); printf("array[0]: %x\n",array[0]); printf("array[1]: %x\n",array[1]); printf("*array[1]: %d\n",*array[1]); printf("*array+1: %x\n",*array+1); printf("*array[2]: %d\n",*array[2]); printf("*array+2: %x\n",*array+2); printf("**array+2: %d\n",**array+2); printf("*(*(array+1)+2): %d\n",*(*(array+1)+2)); printf("*(array+1)+2: %x\n",*(array+1)+2); printf("*array[3]: %x\n",*array[3]); } CSCD 326

  32. array[0][0]: 0 array[0][1]: 1 array[0][2]: 2 array[0][3]: 3 array[1][0]: 4 array[1][1]: 5 array[1][2]: 6 array[1][3]: 7 array[2][0]: 8 array[2][1]: 9 array[2][2]: 10 array[2][3]: 11 array: effff804 array[0]: effff804 array[1]: effff814 *array[1]: 4 *array+1: effff808 *array[2]: 8 *array+2: effff80c **array+2: 2 *(*(array+1)+2): 6 *(array+1)+2: effff81c *array[3]: 0 2D Arrays and Pointers (2) CSCD 326

  33. 81c 808 804 80c 810 814 830 820 824 828 82c 818 10 4 6 3 1 5 2 0 7 8 9 11 2D Arrays and Pointers (3) array: effff804 array[0]: effff804 array[1]: effff814 *array[1]: 4 *array+1: effff808 *array[2]: 8 *array+2: effff80c **array+2: 2 *(*(array+1)+2): 6 *(array+1)+2: effff81c *array[3]: 0 array -- effff804 (804) each row contains 16 bytes array[0] array[1] array[2] CSCD 326

  34. Pointers and Structures • Structures are an aggregate data type of different types struct Student { char FirstName[40]; char LastName[40]; int StudentNum; double GradePointAvg; } Student S; • declares and allocates an entire structure named S Student *Sptr = &S; • declares, allocates and initializes a pointer Sptr which points at S CSCD 326

  35. Struct member access through pointers • One way to access the members of S through Sptr is: (*Sptr).GradePointAvg • since this is awkward at best, an operator has been provided which both dereferences and provides member selection: Sptr->GradePointAvg • this has exactly the same meaning as the previous expression CSCD 326

  36. Structs as parameters • Call by value prototype: void PrintInfo( Student ThisStudent); • results in a copy being made of the entire actual parameter • Call by reference prototype: void PrintInfo( Student & ThisStudent ); • since only the address of the actual parameter is passed no copy is made • Call by constant reference parameter void PrintInfo( const Student & ThisStudent); • here no copy is made and no changes can be made to the actual parameter CSCD 326

  37. Exogenous vs. Indigenous Data • The student struct as illustrated before contains all indigenous data - All data is contained inside the stuct • Exogenous data - data allocated outside the struct but pointed to by an internal pointer • Example: struct Student { char *FirstName; char *LastName; int StudentNum; double GradePointAvg; } Student S; S.FirstName = new char [40]; S.LastName = new char [40]; CSCD 326

  38. Problems with Exogenous Data • In the previous example suppose we have: Student S, T; • if T has been initialized and had space allocated for its strings then: S = T; • does a member by member copy of T into S which means they have pointers to the same FirstName and LastName strings - thus: delete [] T.FirstName erases the string pointed to by S.FirstName • overriding the = operator and copying only pointers is a shallow copy • overriding the = operator and copying the memory holding characters is a deep copy CSCD 326

  39. Linked List Basics • Arrays can be thought of as lists of objects which occupy contiguous memory • Using structures and pointers a list of objects which are located in non-contiguous memory can be built • the basic structure for such a list is shown below: struct Node Diagram: { char Element; Node *next; } Element Next CSCD 326

  40. Linked List Building void main() { Node *head = NULL, *cur; char c; for(c = ‘a’; c <= ‘z’; c++) { if(!head) { head = cur = new Node; head->Element = c; } else { cur->Next = new Node; cur = cur->Next; cur->Element = c; } } cur->Next = NULL; } CSCD 326

More Related