|
Page 6 of 9 Now, moving into the code, we declare two character pointers and show the string on the screen. We then "point" the pointer pA at strA. That is, by means of the assignment statement we copy the address of strA[0] into our variable pA. We now use puts() to show that which is pointed to by pA on the screen. Consider here that the function prototype for puts() is: int puts(const char *s);
For the moment, ignore the const. The parameter passed to puts() is a pointer, that is the value of a pointer (since all parameters in C are passed by value), and the value of a pointer is the address to which it points, or, simply, an address. Thus when we write puts(strA); as we have seen, we are passing the address of strA[0]. Similarly, when we write puts(pA); we are passing the same address, since we have set pA = strA;
Given that, follow the code down to the while() statement on line A. Line A states: While the character pointed to by pA (i.e. *pA) is not a nul character (i.e. the terminating '\0' do the following: Line B states: copy the character pointed to by pA to the space pointed to by pB, then increment pA so it points to the next character and pB so it points to the next space. When we have copied the last character, pA now points to the terminating nul character and the loop ends. However, we have not copied the nul character. And, by definition a string in C must be nul terminated. So, we add the nul character with line C. It is very educational to run this program with your debugger while watching strA, strB, pA and pB and single stepping through the program. It is even more educational if instead of simply defining strB[] as has been done above, initialize it also with something like: strB[80] = "12345678901234567890123456789012345678901234567890"
where the number of digits used is greater than the length of strA and then repeat the single stepping procedure while watching the above variables. Give these things a try! Getting back to the prototype for puts() for a moment, the "const" used as a parameter modifier informs the user that the function will not modify the string pointed to by s, i.e. it will treat that string as a constant.
Of course, what the above program illustrates is a simple way of copying a string. After playing with the above until you have a good understanding of what is happening, we can proceed to creating our own replacement for the standard strcpy() that comes with C. It might look like:
char *my_strcpy(char *destination, char *source) { char *p = destination; while (*source != '\0') { *p++ = *source++; } *p = '\0'; return destination; } In this case, I have followed the practice used in the standard routine of returning a pointer to the destination.
Again, the function is designed to accept the values of two character pointers, i.e. addresses, and thus in the previous program we could write: int main(void) { my_strcpy(strB, strA); puts(strB); }
I have deviated slightly from the form used in standard C which would have the prototype: char *my_strcpy(char *destination, const char *source);
Here the "const" modifier is used to assure the user that the function will not modify the contents pointed to by the source pointer. You can prove this by modifying the function above, and its prototype, to include the "const" modifier as shown. Then, within the function you can add a statement which attempts to change the contents of that which is pointed to by source, such as:
*source = 'X';
which would normally change the first character of the string to an X. The const modifier should cause your compiler to catch this as an error. Try it and see.
|