Post on 21-Dec-2015
transcript
CS 1400
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.
More C-string functions…
void strncpy (char d[ ], char s[ ], int length);
copy exactly length characters from string s into string d.
char* strstr (char s[ ], char p[ ]);
return a reference (pointer) to the first occurence of string p in string s – or NULL if not found.
Arrays of C-strings
• Arrays of C-strings are just 2-D arrays of characterschar names[10][30]; // 10 names of up to 29 chars ea.
• 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.
Fred 93.4
John 87.1
Cheryl 96.9
Shannon 81.2
George 77.2
… …
Pseudocode…
• read in database from a file into two parallel arrays
• get a particular name from the user
• do a linear search for the name
• output the corresponding 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-stringsvoid 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-stringsvoid 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…12Fizz4 BuzzFizz78FizzBuzz11Fizz1314FizzBuzz…
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-spelledA 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
h e l p \0word
(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
x
y
0x200 0x202 0x204
0x300 0x304
100 200 300
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);
Pointers vs. References
• A reference and a pointer both refer or point to a memory location.– A reference is managed by the system– A pointer is managed by the programmer
Pointer variables
• A variable may be declared to hold an address using the * symbolfloat *fptr; // may hold an address of a floatshort *iptr; // may hold an address of a short
• The address of a variable or cell may be determined using the & operatorfloat b = 3.14; short c = 567;fptr = &b;iptr = &c;
fptr
iptr
3.1400000
0x400
0x400
0x500
0x500
567
or more commonly diagrammed using arrows…
fptr
iptr
3.1400000
0x400
0x500
567
a
b
a
b
Using pointer variables
• A cell value pointed to by a pointer variable may be referenced using the * operatorcout << *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;
fptr++;
cout << *fptr << endl;
fptr += 2;
cout << *fptr << endl;
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 (a reference managed // by the system)!
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.
Equivalent notation…
Pointer notation Array notation
void MyFunc (char *array); void MyFunc (char array[ ]);
*(array+1) = ‘x’; array[1] = ‘x’;
MyFunc (letters); MyFunc (&letters[0]);
float *fptr; float fptr[ ];
MyFunc (letters+n); MyFunc (&letters[n]);
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;
John Jacob Jinglehiemer Schmidt
Alloitious Promethius Quoroyo Gildersleve
Mahatma Moriajib Mattesumium Matilda
Maria Cecila Prozelli Motsorelli Puchini
Alfred Erasmus Nobelius Scarlotta Newman
char names[N][200]; // names is a reference
char *nameptrs[N]; // nameptrs is a pointer array
John Jacob Jinglehiemer Schmidt
Alloitious Promethius Quoroyo Gildersleve
Mahatma Moriajib Mattesumium Matilda
Maria Cecila Prozelli Motsorelli Puchini
Alfred Erasmus Nobelius Scarlotta Newman
nameptr names
0
1
2
3
4
After sorting…
John Jacob Jinglehiemer Schmidt
Alloitious Promethius Quoroyo Gildersleve
Mahatma Moriajib Mattesumium Matilda
Maria Cecila Prozelli Motsorelli Puchini
Alfred Erasmus Nobelius Scarlotta Newman
nameptrs names
0
1
2
3
4
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;
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); }}
We’ll use a Selection Sort…
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;}
FindSmallest()
Swap()
void Swap (char *list[ ], int j, int k){ char *temp; temp = list[j]; list[j] = list[k]; list[k] = temp;}