410 likes | 520 Views
CS 1400 Apr 6, 2007. Chapters 9, 10 C-strings and Pointers. A few C-string library functions…. #include <cstring> int strcmp (char a[ ], char b[ ]); returns <0 if string a is less than string b, returns 0 if the strings are the same, and returns >0 if string a is greater than string b
E N D
CS 1400Apr 6, 2007 Chapters 9, 10 C-strings and Pointers
A few C-string library functions… #include <cstring> int strcmp (char a[ ], char b[ ]); returns <0 if string a is less than string b, returns 0 if the strings are the same, and returns >0 if string a is greater than string b int strlen (char a[ ]); returns the number of characters in string a void strcpy (char dest[ ], char source[ ]); copies the source string into the destination array (including the null), but does no bounds checking.
Arrays of C-strings • Arrays of C-strings are just 2-D arrays of characters char names[10][30];// 10 names of up to 29 chars • Rules of thumb: • names refers to the entire array of names and is used to pass the array to a function. • names[n] refers to a single name and can be used to pass a single name to a function or for input and ouput. • names[n][m] refers to a single character.
Examples • cin >> names[2]; • inputs a name into row 2 (the 3rd name) • names[2][1] = ‘x’; • changes the 2nd character in row 2 to ‘x’ • MyFunc (names); • passes the entire list of names to a function with this prototype; void MyFunc (char thesenames[ ] [30]); • MyFunc2 (names[2]); • passes the 3rd name to a function with this prototype; void MyFunc2 (char thisname[ ]);
Example… Consider a file of 100 student names and grades called “students.txt” Write a program to accept a name from the user and then output this student’s grade.
int main ( ) { char names[100][30], thisname[30]; float grades[100]; ifstream fin; fin.open (“students.txt”); for (int n=0; n<100; n++) fin>>names[n] >> grades[n]; cout << “enter a name: “; cin >> thisname; cout << “the grade is: “ << grades[LinearSearch(names, 100, thisname)] << endl; return 0; }
LinearSearch() for C-strings… int LinearSearch (char list[ ][30], int size, char value[ ]) { bool found = false; int position = -1; for (int n=0; n<size && !found; n++) { if (strcmp(list[n], value) == 0) { position = n; found = true; } } return position; }
SelectionSort() for C-strings void SelectionSort (char array[ ][30], int size) { int smallest_position; for (int n=0; n<size-1; n++) smallest_position = FindSmallest (array, n, size); Swap (array, n, smallest_position); }
Swap() for C-strings void Swap (char a[ ][30], int n, int k) { char temp[30]; strcpy (temp, a[n]); strcpy (a[n], a[k]); strcpy (a[k], temp); }
FindSmallest() for C-strings int FindSmallest (char array[ ][30], int start, int size) { int position; char smallest[30]; strcpy (smallest, array[start]); // first assumption for (int k=start+1; k<size; k++) if (strcmp (array[k], smallest) < 0) { strcpy (smallest, array[k]); // change your mind position = k; // and remember pos. } return position; }
Common interview question… Write a program that prints out the numbers 1 to 100 on their own line; except if the number is a multiple of 3, write only the word “Fizz” on its own line, if the word is a multiple of 5, write only the word “Buzz” on its own line, and if the word is a multiple of both, write only the word “FizzBuzz” on its own line.
Example output lines… 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz …
int main() { for (int n=1; n<=100; n++) { if ((n%3 == 0) && (n%5 == 0)) cout << “FizzBuzz\n”; else if (n%3 == 0) cout << “Fizz\n”; else if (n%5 == 0) cout << “Buzz\n”; else cout << n << endl; } }
Example… • Write a program that will accept a textual file name and then output all the words in that file that are miss-spelled A spell-checker! Enter filename: myletter.txt Miss-spelled words: ardvarc reciept requiam
Pointers, values, and names • Each memory cell has • a value • an address char word[5] = “HELP”; // each cell is one byte 0x100 0x101 0x102 0x103 0x104 word h e l p \0 (Addresses are typically given in hexadecimal notation)
Different data types my require different sized cells short x[3] = {100, 200, 300}; // each cell is two bytes float y[2] = {1.2, 3.4}; // each cell is four bytes 0x200 0x202 0x204 x y 100 200 300 0x300 0x304 1.20000000 3.40000000
sizeof() function • The number of bytes utilized by a particular system for a variable may be determined by the sizeof() function; • The argument to sizeof() may be a type or a variable name cout << sizeof(short) << sizeof(float); cout << sizeof(x) << sizeof(y);
Pointer variables • A variable may be declared to hold an address using the * symbol float *fptr; // may hold an address of a float short *iptr; // may hold an address of a short • The address of a variable or cell may be determined using the & operator float b = 3.14; short c = 567; fptr = &b; iptr = &c;
0x400 fptr a 0x400 3.1400000 0x500 b 567 iptr 0x500 or more commonly diagrammed using arrows… 0x400 a fptr 3.1400000 0x500 b 567 iptr
Using pointer variables • A cell value pointed to by a pointer variable may be referenced using the * operator cout << *iptr; // output value pointed to by iptr cout << *fptr; // output value pointed to by fptr So, the * operator means “value pointed to by”
Confusing use of * • Be careful! • When used in a declaration, * creates a pointer variable int *ptr; • When used as a unary operator, * resolves or dereferences (uses) a pointer. cout << *ptr; • When used between two values, * means multiply cout << cost * rate;
Confusing use of & • Be careful! • When used in a declaration, & creates a reference variable void MyFunc (int &ptr); • When used as a unary operator, & determines a pointer. cout << &ptr;
Pointer arithmetic • Pointer variables may be incremented, decremented, or have constants added or subtracted. • When a pointer variable is incremented, the computer will automatically increment the address by the appropriate number of cells – regardless of their size
Examples… float x[4] = {1.2, 3.4, 5.6, 7.8}; float *fptr = &x[0]; cout << *fptr << endl; // outputs 1.2 fptr++; // advance to the next cell cout << *fptr << endl; // outputs 3.4; fptr += 2; // advance 2 more cells cout << *fptr << endl; // outputs 7.8
The * and & operators have high precedence… • int cost, *value, temp, rate; • value = &rate; • cin >> cost >> rate; • temp = cost * * value; What would be stored in temp if the user enters 2.5 and 2?
Pointers may be passed as function parameters… void MyFunc (int *p1, int *p2); int main() { int x = 55, y = 77; MyFunc (&x, &y); cout << x << “, “, << y << endl; }
void MyFunc (int *p1, int *p2) { int temp; temp = *p1; *p1 = *p2; *p2 = temp; } So… what does this function do?
Arrays and pointers • When an array is declared, the system creates the array cells and a pointer variable to the array: char letters[5]; letters
Examples… char letters[5] = “HELP”; cout << *letters << endl; cout << letters[0] << endl; cout << *(letters+2) << endl; cout << letters[2] << endl; letters++; // illegal – letters is a constant // pointer!
Passing arrays… • What is being passed? MyFunc (letters); • What should the function prototype be? void MyFunc (char array[ ]); // ?? void MyFunc (char *array); // ?? Either! These are equivalent: The parameter array is a pointer to a char array.
2-D arrays and pointers • You may visualize a 2-D array as follows; char names[5][10]; names names[n] names[n][m]
Dynamically allocated memory • Using pointers, array space can be allocated manually to a size determined at run-time! int size; char *docptr; cout << “Enter document size: “; cin >> size; docptr = new char[size] ;
Deallocating… • Memory allocated using new can be manually deallocated using delete delete [ ] docptr; • Memory allocated using new that is not manually deallocated is automatically deallocated when a program exits
Sorting arrays with pointers • Consider a table of long names;
char names[N][200]; char *nameptrs[N]; nameptr names 0 1 2 3 4 John Jacob Jinglehiemer Schmidt Alloitious Promethius Quoroyo Gildersleve Mahatma Moriajib Mattesumium Matilda Maria Cecila Prozelli Motsorelli Puchini Alfred Erasmus Nobelius Scarlotta Newman
After sorting… nameptrs names 0 1 2 3 4 John Jacob Jinglehiemer Schmidt Alloitious Promethius Quoroyo Gildersleve Mahatma Moriajib Mattesumium Matilda Maria Cecila Prozelli Motsorelli Puchini Alfred Erasmus Nobelius Scarlotta Newman
Program… char names[N][200]; char *nameptrs[N]; for (int n=0; n<N; n++) { cin >> names[n]; nameptrs[n] = names[n]; } SortByPointer (names, nameptrs); for (int n=0; n<N; n++) cout << *(nameptrs[n]) << endl;
We’ll use a Selection Sort… void SortByPointer (char names[ ][100], char *nameptrs[ ]) { int smallest_position; for (int n=0; n<N-1; n++) {smallest_position = FindSmallest (nameptrs, n, N); Swap (nameptrs, n, smallest_position); } }
FindSmallest() int FindSmallest (char *list[ ], int start, int size) { int position; char *smallest = list[start]; for (int k=start+1; k<size; k++) if (strcmp(list[k], smallest) < 0) { smallest = list[k]; position = k; } return position; }
Swap() • void Swap (char *list[ ], int j, int k) • { char *temp; • temp = list[j]; • list[j] = list[k]; • list[k] = temp; • }