Question

I tried to solve this problem, which is to count the amount of lines, blank spaces, and tabs.

My solution was incorrect because I don't know how to use { }.

main ()
{

    int newline; 
    int tab; 
    int blank;
    int c;

    newline = 0;
    tab = 0;
    blank = 0;

    while ((c = getchar()) != EOF) 
        if (c == '\n')
            ++newline;
        if (c == '\t')
            ++tab;
        if (c == 32)
            ++blank;

    printf("lines: %d tabs: %d blanks: %d\n", newline, tab, blank);
}

In my code, only new lines were being counted. Tabs and spaces were never counted. I know the answer is to add { } around the if statements section. But I only know this because I searched google for the solution.

Perhaps it is just me, but K&R do not really explain when I should use { }.

Can someone explain how I can know to add { } to my above code? When I read the code, it seems fine without {}. It means I truly don't understand its usage. Why aren't tabs and spaces counted in the above code?

Is there another book on C that you can recommend? I have no programming experience.

Was it helpful?

Solution 2

One relatively straightforward "rule of thumb": Look for the semi-colon(s). Referring to your example, starting at the "while", read forward until you see a semi-colon. If you want anything beyond that semi-colon to be executed as part of your while block, you need to wrap it all in curly braces.

Another way to look at it: The semi-colon is a statement terminator. It terminated blank = 0 as your previous statement; it terminates not only the if but also the enclosing while statement. Thus, to execute the following if as part of the while block, you need to enclose the ifs in curly braces.

Oh, and by the way, C and similar languages do not attach syntactic meaning to whitespace. It is at most treated as a separator. Any indentation you choose to apply is for the benefit of the human reader only; it has no significance to the compiler.

OTHER TIPS

The syntax of a simple if is : if (<condition>) <statement>. The <statement> can be a single statement (as you have in your code) or it can be a block (zero or more statements enclosed in braces). When you have a single statement, it is strictly a question of style whether you surround it with braces—the behavior is the same.

Any if/while/for can be followed by a single statement without braces, or any number of statements encapsulated in braces. If you write an if/while/for followed by many statements and no braces, only the first statement falls under the if/while/for. Note that whatever whitespace you use does not matter, it is only for readability.

This is the equivalent of your code if it was written with braces:

while ((c = getchar()) != EOF) 
{
    if (c == '\n')
    {
        ++newline;
    }
}

if (c == '\t')
{
   ++tab;
}

if (c == 32)
{
   ++blank;
}

What you want:

while ((c = getchar()) != EOF) 
{
   if (c == '\n')
   {
       ++newline;
   }

   if (c == '\t')
   {
      ++tab;
   }

   if (c == 32)
   {
      ++blank;
   }
}

which is equivalent to

while ((c = getchar()) != EOF) 
{
   if (c == '\n')
       ++newline;

   if (c == '\t')
      ++tab;

   if (c == 32)
      ++blank;
}

Exclusion of braces serves absolutely no purpose but style. If you are ever in doubt, include the braces.

Braces ({ and }) are used to convert zero or more statements into a single compound statement. Anywhere you wish for a group of statments to be treated as a single statement you should use braces.

For example, a while loop executes a single statement whilst it evaluates to true:

  while(some-condition)
    statement

Obvious there will be times when you want to execute multiple statements, and this is where you surround them with { and } in order to turn them into a single compound statement.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top