Step 6 of 10
Strings through pointers
Strings are char arrays, and a string passed to a function arrives as a char * pointing at its first character. Walking a string with a pointer is the most common pointer code in C, so it's worth getting fluent with it.
#include <stdio.h>
int count_vowels(const char *s) {
int count = 0;
for (const char *c = s; *c != '\0'; c++) {
if (*c == 'a' || *c == 'e' || *c == 'i' || *c == 'o' || *c == 'u') {
count++;
}
}
return count;
}
int main(void) {
printf("%d\n", count_vowels("programming in c"));
return 0;
}
4
Reading the loop
const char *c = sstarts a pointer at the first character.*c != '\0'keeps going until the terminator.c++moves to the next character.- Inside,
*cis the current character.
It does the same thing as for (int i = 0; s[i] != '\0'; i++) with s[i]. Both styles are common; the pointer version is idiomatic C and shows up in the standard library's own code.
String literals are read-only
A literal like "programming in c" must never be modified: writing to it is undefined behavior. On most desktop systems literals live in read-only memory, so an attempt crashes; on others it silently misbehaves. You can point at a literal with a const char *, and the const makes the compiler stop you from writing through it. Declaring parameters as const char * lets callers pass literals safely, and the compiler will stop you if the function tries to modify them.
Your turn: write int count_char(const char *s, char ch) that returns how many times ch appears in s.