Strings: Iteration
On the previous page we learned that a string in C is just an array of individual characters ending with zero, and ended the page with the following for loop that iterates over all the characters of the string:
for (i = 0; str[i]; ++i) { /* the condition means: str[i] != 0 */
...
}
This is a good time to introduce a very common C idiom which allows us to iterate a string without having a variable for an index.
First, you should remember that if p is a pointer to a value of some type, storing some address in memory, *p gives that value. Then, you should also remember that an array can be "decayed" to the pointer to its 0th element. These two facts combined allow us to write the following loop:
char *p;
for (p = s; *p; ++p) {
...
}
What happens here? p starts from s, which is the same as &s[0], pointer to the 0th element. The loop condition is *p, which is the same as *p != 0, which means "while p does not point to the zero character at the end of the string". ++p will increment p as a pointer, so it points to the next element of the string. So this for loop will iterate over all the characters until it sees zero, and then stop.
In some cases, if we don't need to preserve the pointer to the beginning of the string, we can even modify s:
for ( ; *s; ++s) {
...
}
If this does not make much sense, consider this implementation of the function that prints a string:
void print_string(char *str) {
for ( ; *str; ++str) {
putchar(*str);
}
}
Note that this function changes its parameter, but since it's passed by value, it won't change the original variable.
Try running this code:
#include <stdio.h>
void print_string(char *str) {
for ( ; *str; ++str) {
putchar(*str);
}
}
int main() {
char s[] = "hello, this is a string\n";
print_string(s);
print_string(s);
return 0;
}
Note that the first invocation of print_string did not change s in any way by moving its str parameter (it could not!) It could change the individual characters though, consider this:
#include <stdio.h>
void print_string_and_change(char *str) {
for ( ; *str; ++str) {
putchar(*str);
if (*str == ' ') {
*str = '*';
}
}
}
int main() {
char s[] = "hello, this is a string\n";
print_string_and_change(s);
print_string_and_change(s);
return 0;
}
In this example, the first invocation of print_string_and_change changes some characters in the string, and since the string is effectively passed as a pointer, it gets updated in the original char s[] in main, so the second invocation prints the updated string.
On the next page, we'll start learning some basic string operations: string length, copying strings, and more!