This is C! It's designed to be terse!
int count_chars(const char* string, char ch)
{
int c = 0;
while (*string) c += *(string++) == ch;
return c;
}
Update
I'll try and explain how it works:
int c = 0;
This will be the count of the number of matches that have been found.
while (*string)
This is the loop control statement and will continue to iterate the loop as long as the condition is true. In this case the condition is *string
. In C, strings are stored 'null terminated' which means the last character of the string is a character with value 0 ('\0'). *string
evaluates to the character the pointer is pointing to. Expressions in C are 'true' if they evaluate to any non-zero value and 'false' if they evaluate to zero. *string
is an expression, so any non-zero character *string
points to is true and the '\0' at the end of the string is false. So this will terminate if *string
is pointing to the end of the string.
*(string++)
This is an expression which evaluates to the value the pointer is pointing at. The ++
is a post-increment so the value of the pointer is moved one place forward, i.e. it points to the next character in the string. Note the the value of the expression is not the same as the value of *string
after the expression has been evaluated because the pointer has moved.
*(string++) == ch
This is a comparison expression, it compares the value of *string
(before it was updated) to the value of ch
. In C, the result of this is an integer (there's no bool type in C) which has the value '1' if the expression is true and '0' if the expression is false.
c += *(string++) == ch;
We know the bit after the +=
is a '1' if the character is one we're looking for and '0' if not. The +=
is shorthand for:
c = c + (*(string++) == ch);
so it will increment the count if a matching character has been found.
In this particular case, there's little advantage to the +=
syntax, but if c
was more complex, say *(variable [index].structure_member [index2])
then it would only be evaluated once.
The ;
at the end marks the end of the statement and because there's no {
after the while
, it also marks the end of the while
loop.