nixawk / hello-c

c programming
9 stars 11 forks source link

c - STATEMENTS AND CONTROL FLOW #18

Open nixawk opened 7 years ago

nixawk commented 7 years ago

This section describes how to organize statements into logical thoughts and how to format various kinds of statements. The general principles for writing clear statements are as follows:

nixawk commented 7 years ago

Statement Placement

It is recommended that you use explicit comparison even if the comparison value will never change. For example, this statement:

if (!(bufsize % sizeof(int)))

should be written instead as

if ((bufsize % sizeof(int)) == 0)

to reflect the numeric (not boolean) nature of the test.

nixawk commented 7 years ago

Braces

Compound statements, also known as blocks, are lists of statements enclosed in braces. The brace style we recommend is the Braces-Stand-Alone method. Place braces on separate lines and align them. This style, which is used throughout this document, allows for easier pairing of the braces and costs only one vertical space.

Example: Braces-Stand-Alone method

for (i = 0, j = strlen(s)-1; i < j; i++, j--)
{
    c = s[i];
    s[i] = s[j];
    s[j] = c;
}

Although C does not require braces around single statements, there are times when braces help improve the readability of the code. Nested conditionals and loops can often benefit from the addition of braces, especially when a conditional expression is long and complex.

The following examples show the same code with and without braces. We encourage the use of braces to improve readability. Use your own judgment when deciding whether or not to use braces, remembering that what is clear to you may not be obvious to others who read your code.

Example: braces improve readability

for (dp = &values[0]; dp < top_value; dp++)
{
    if (dp->d_value == arg_value
     && (dp->d_flag & arg_flag) != 0)
    {
        return (dp);
    }
}
return (NULL);

Example: no braces

for (dp = &values[0]; dp < top_value; dp++)
    if (dp->d_value == arg_value
     && (dp->d_flag & arg_flag) != 0)
        return (dp);
return (NULL);
for (sy = sytable; sy != NULL; sy = sy->sy_link)
{
    if (sy->sy_flag == DEFINED)
    {
        ...
    } /* if defined */
    else
    {
        ...
    } /* if undefined */
}     /* for all symbols */
/* Locate end of string */
for (char_p = string; *char_p != EOS; char_p++)
    ; /* do nothing */
nixawk commented 7 years ago

Selection Control Statements

This section discusses the recommended formatting for selection control statements. Examples are given to show how to format single statements as well as blocks of statements.

If

if (expression)
    one_statement;
if (expression)
{
    statement_1;
    ...
    statement_n;
}

If Else

if (expression)
    statement
else
    statement
if (expression)
    one_statement;
else
{
    statement_1;
    ...
    statement_n;
}

Else If

For readability, use the following format for else if statements:

if (expression)
    statement[s]
else if (expression)
    statement[s]
else
    statement[s]

Nested If Statements

If If If

Use nested if statements if there are alternative actions (i.e., there is an action in the else clause), or if an action completed by a successful evaluation of the condition has to be undone. Do not use nested if statements when only the if clause contains actions.

Example: good nesting

status = delta_create((Callback)NULL, &delta);
if ( status == NDB_OK )
{
    if ((status = delta_record_condition(...)) == NDB_OK &&
        (status = delta_field_condition(...)) == NDB_OK &&
        (status=delta_field_condition(...)) == NDB_OK )

      status = delta_commit(delta, ...);

  (void)ndb_destroy_delta( delta);
}

Example: inappropriate nesting

status = delta_create((Callback)NULL, &delta);
if (status == NDB_OK)
{
    status = delta_record_condition( delta, ...);
    if (status == NDB_OK )
    {
        status = delta_field_condition(delta, ...);
        if (status == NDB_OK )
        {
            status = delta_field_condition( ...);
            if (status == NDB_OK )
                status = delta_commit(delta, ...);
        }
    }
    (VOID)ndb_destroy_delta(delta);
}
return(status);

If If Else

Because the else part of an if else statement is optional, omitting the “else” from a nested if sequence can result in ambiguity. Therefore, always use braces to avoid confusion and to make certain that the code compiles the way you intended. In the following example, the same code is shown both with and without braces. The first example will produce the results desired. The second example will not produce the results desired because the “else” will be paired with the second “if” instead of the first.

Example: braces produce desired result

if (n > 0)
{
    for (i = 0; i < n; i++)
    {
        if (s[i] > 0)
        {
            printf("...");
            return(i);
        }
    }
}
else /* CORRECT -- braces force proper association */
    printf("error - n is zero\n");

Example: absence of braces produces undesired result

if (n > 0)
    for (i = 0; i < n; i++)
        if (s[i] > 0)
        {
            printf("...");
            return(i);
        }
        else /* WRONG -- the compiler will match to closest */
                /* else-less if */
           printf("error - n is zero\n");

Switch

For readability, use the following format for switch statements:

switch (expression)
{
    case aaa:
        statement[s]
        break;
    case bbb: /* fall through */
    case ccc:
        statement[s]
        break;
    default:
        statement[s]
        break;
}

Note that the fall-through feature of the C switch statement should be commented for future maintenance.

All switch statements should have a default case, which may be merely a “fatal error” exit. The default case should be last and does not require a break, but it is a good idea to put one there anyway for consistency.

nixawk commented 7 years ago

Iteration Control Statements

This section discusses the recommended formatting for iteration control statements. Examples are given to show how to format single statements as well as blocks of statements.

While

For one statement, use the following format:

while (expression)
    one_statement;

For a block of statements, use:

while (expression)
{
    statement_1;
    ...
    statement_n;
}

For

Use the following formats:

for (expression)
    one_statement;

for (expression)
{
    statement_1;
    ...
    statement_n;
}

If a for loop will not fit on one line, split it among three lines rather than two:

for (curr = *listp, trail = listp;
    curr != NULL;
    trail = &(curr->next), curr = curr->next)
{
    statement_1;
    ...
    statement_n;
}

Do While

For readability, use the following format:

do
{
    statement_1;
    statement_2;
    statement_3;
}
while (expression)