The i < n test stops the loop after n characters have been copied. The second part of the test, the expression str[i], is the code for the character about to be copied. If the loop reaches the null character, the code is 0, and the loop terminates. The final while loop terminates the string with the null character and then sets the rest of the allocated space, if any, to null characters.
Another approach for setting the size of the new string is to set n to the smaller of the passed value and the string length:
int len = strlen(str);
n = (n < len) ? n : len; // the lesser of n and len
char * p = new char[n+1];
This ensures that new doesn’t allocate more space than what’s needed to hold the string. That can be useful if you make a call such as left("Hi!", 32767). The first approach copies the "Hi!" into an array of 32767 characters, setting all but the first 3 characters to the null character. The second approach copies "Hi!" into an array of 4 characters. But by adding another function call (strlen()), it increases the program size, slows the process, and requires that you remember to include the cstring (or string.h) header file. C programmers have tended to opt for faster running, more compact code and leave a greater burden on the programmer to use functions correctly. However, the C++ tradition places greater weight on reliability. After all, a slower program that works correctly is better than a fast program that works incorrectly. If the time taken to call strlen() turns out to be a problem, you can let left() determine the lesser of n and the string length directly. For example, the following loop quits when m reaches n or the end of the string, whichever comes first:
int m = 0;
while (m <= n && str[m] != '\0')
m++;
char * p = new char[m+1]:
// use m instead of n in rest of code
Remember, the expression str[m] != '\0' evaluates to true when str[m] is not the null character and to false when it is the null character. Because nonzero values are converted to true in an && expression and zero is converted to false, the while test also can be written this way:
while (m<=n && str[m])
Function Overloading
Function polymorphism is a neat C++ addition to C’s capabilities. Whereas default arguments let you call the same function by using varying numbers of arguments,
Overloaded functions are analogous to verbs having more than one meaning. For example, Miss Piggy can root at the ball park for the home team, and she can root in soil for truffles. The context (one hopes) tells you which meaning of
The key to function overloading is a function’s argument list, also called the
void print(const char * str, int width); // #1
void print(double d, int width); // #2
void print(long l, int width); // #3
void print(int i, int width); // #4
void print(const char *str); // #5
When you then use a print() function, the compiler matches your use to the prototype that has the same signature:
print("Pancakes", 15); // use #1
print("Syrup"); // use #5
print(1999.0, 10); // use #2
print(1999, 12); // use #4
print(1999L, 15); // use #3
For example, print("Pancakes", 15) uses a string and an integer as arguments, and it matches Prototype #1.
When you use overloaded functions, you need to be sure you use the proper argument types in the function call. For example, consider the following statements:
unsigned int year = 3210;
print(year, 6); // ambiguous call