All versions of both standards since then (C99 and C++98) have maintained the same idea. We rely on automatically generated member functions in C++, and few people write explicit return;
statements at the end of a void
function. Reasons against omitting seem to boil down to "it looks weird" "it looks weird". If, like me, you're curious about the rationale for the change to the C standard read this question read this question. Also note that in the early 1990s this was considered "sloppy practice" because it was undefined behavior (although widely supported) at the time.
All versions of both standards since then (C99 and C++98) have maintained the same idea. We rely on automatically generated member functions in C++, and few people write explicit return;
statements at the end of a void
function. Reasons against omitting seem to boil down to "it looks weird". If, like me, you're curious about the rationale for the change to the C standard read this question. Also note that in the early 1990s this was considered "sloppy practice" because it was undefined behavior (although widely supported) at the time.
All versions of both standards since then (C99 and C++98) have maintained the same idea. We rely on automatically generated member functions in C++, and few people write explicit return;
statements at the end of a void
function. Reasons against omitting seem to boil down to "it looks weird". If, like me, you're curious about the rationale for the change to the C standard read this question. Also note that in the early 1990s this was considered "sloppy practice" because it was undefined behavior (although widely supported) at the time.
I see a number of things that may help you improve your code.
Use const
where possible
The word_counter
function does not (and should not) alter the passed string and so the parameter should therefore be declared const
.
int word_counter(const char string[])
Evaluate each character only once
There's no need to back up and test the previous character to see if it's whitespace or not -- it was already evaluated the last time through the loop! What's needed then, is just to remember that result. One way to do that would be to use a boolean variable to keep track of whether we're in a word or not in a word. Here's a rework showing how that might look:
#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>
int word_counter(const char string[])
{
int count = 0;
for (bool inword = false; *string; ++string) {
if (isspace(*string)) {
if (inword) {
inword = false;
}
} else { // not whitespace
if (!inword) {
inword = true;
++count;
}
}
}
return count;
}
As noted in the other review, you should use isspace()
because tab, spaces, form-feeds, vertical tabs and newlines are all things that might separate words.
Understand the concept of a locale
It's often ignored or overlooked, but the isspace
function and its siblings in ctype.h
may change behavior under POSIX or POSIX-like environments, depending on the locale
that's currently in use. It's not a reason to avoid using these functions, but it's good to be aware of the subtle details.
Omit return 0
When a C or C++ program reaches the end of main
the compiler will automatically generate code to return 0, so there is no need to put return 0;
explicitly at the end of main
.
Note: when I make this suggestion, it's almost invariably followed by one of two kinds of comments: "I didn't know that." or "That's bad advice!" My rationale is that it's safe and useful to rely on compiler behavior explicitly supported by the standard. For C, since C99; see ISO/IEC 9899:1999 section 5.1.2.2.3:
[...] a return from the initial call to the
main
function is equivalent to calling theexit
function with the value returned by themain
function as its argument; reaching the}
that terminates themain
function returns a value of 0.
For C++, since the first standard in 1998; see ISO/IEC 14882:1998 section 3.6.1:
If control reaches the end of main without encountering a return statement, the effect is that of executing return 0;
All versions of both standards since then (C99 and C++98) have maintained the same idea. We rely on automatically generated member functions in C++, and few people write explicit return;
statements at the end of a void
function. Reasons against omitting seem to boil down to "it looks weird". If, like me, you're curious about the rationale for the change to the C standard read this question. Also note that in the early 1990s this was considered "sloppy practice" because it was undefined behavior (although widely supported) at the time.
So I advocate omitting it; others disagree (often vehemently!) In any case, if you encounter code that omits it, you'll know that it's explicitly supported by the standard and you'll know what it means.