syque.com

The Psychology of Quality and More

| Menu | Books | Share | Search | Settings |

C Style: Standards and Guidelines (contents)

CHAPTER 6 : Layout

PART 3 : LAYOUT

CHAPTER 6 : Code Layout
6.1 Basic principles of code layout
6.2 Use of Spaces
6.3 Use of blank lines
6.4 Use vertical alignment
6.5 Indentation level
6.6 Line wrapping
6.7 Braces
6.8 Use of parentheses
6.9 Nested single statement
6.10 Empty statements
6.11 'else..if'
6.12 'switch' statements
6.13 'do..while'
6.14 Labels
6.15 Data declarations
6.16 Function declaration
6.17 Preprocessor commands
6.18 Summary

<--Prev page | Next page -->

 

6.15  Data declarations

Data is often one of the less clear elements of a program and taking time to keep the layout clear is particularly worthwhile.

6.15.1  Ordering specifiers

A declaration consists of a combination of type qualifier (const, volatile) storage class specifier (auto, register, extern or static) and type specifiers (unsigned, signed, char, short, int, long, float, double, structs, union's, enum's, typedef's). The order in which they are used may vary:

 

int long unsigned extern AuthorName  /* this way?        */
extern long unsigned int AuthorName  /* ..or this way??  */

------------------------------------------------------------

The clearest, most portable and most common way is to start with storage class specifiers, follow with type qualifiers (if any) and then type specifiers. Within type specifiers, saying int long is equivalent to saying 'man tall'. It is proper English to put the adjectives before the noun: 'tall man'. The C equivalent is long int. It is also common to put signed or unsigned first. Thus:

 

extern unsigned long int AuthorName  /* this way!!       */

 

6.15.2  One declaration per line

Variables of the same type can be declared on the same line, although this can cause readability problems:

 

int     *FirstPrime,i;

 

Here, i has a physical, but not logical, association with FirstPrime; it is also difficult to find. Also, the variables cannot be commented separately. Putting only closely associated variables in the same statement, but on separate lines, solves many, but not all problems:

 

int     *FirstPrime,
        SecondPrime;

 

This can still cause editing problems, and if a page break occurs between the two lines, SecondPrime is left dangling anonymously. This format can also cause problems with const and volatile. It is simpler and more explicit to declare each variable separately. Logical association is shown with vertical proximity:

 

int     *FirstPrime;
int     SecondPrime;

 

6.15.3  Aligning data declarations

Data declarations contain at least two distinct parts, the type and the identifier. The reader of a program will typically scan lists of data declarations when looking for a known variable name. Vertically aligning identifiers helps this process (as well as making it tidier in appearance):

 

int     DB_Status;
int     NodeID;
char    NodeName[NAME_LEN];

 

Strict adherence to this means that the name always starts in the same column. If the column position is already passed, then the name will start in the standard column, but on the next line:

 

int     DB_Status;
struct DB_NODE                    /* this has passed the standard column.. */
        CurrNode;                 /* ..so the name wraps to the next line  */
int     NodeID;

------------------------------------------------------------------------------

This may be relaxed to allow variable alignment columns, where items need vertically align only in the current 'chunk'. This 'toothbrush' approach however may cause space problems on the line:

 

int               DB_Status;      /* Start of Chunk 1 */
struct DB_NODE    CurrNode;

int     EmpName;                  /* Start of Chunk 2 */

 

The alternative is to allow ragged alignment, which is not as clear as vertically alignment:

 

int     DB_Status;
struct DB_NODE CurrNode;
int     NodeID;

 

6.15.4  Table layout

Data tables can be made more readable by vertically aligning declarations and initializers:

 

struct
{
    char    DayName[DAY_NAME_LEN];
    int     WorkHours;
    float   OvertimeRate;
} WorkRates[]
      = {   { "Monday",     8,  1.0 },
            { "Tuesday",    8,  1.0 },
            { "Wednesday",  8,  1.0 },
            { "Thursday",   8,  1.0 },
            { "Friday",     8,  1.0 },
            { "Saturday",   0,  1.5 },
            { "Sunday",     0,  2.0 },
        };

 

Note how braces are used to contain groups. Note also the comma on the last data line - this avoids problems when further lines are be added.

6.15.5  Pointer layout

In pointer declarations the asterisk is commonly put adjacent to the variable name, as this is how it will be used in statements. An alternative is to associate it in the declaration more closely with the type:

 

char    *ScreenName;    /* "*ScreenName is a char"          */

 

..or..

 

char *  ScreenName;     /* "ScreenName points to a char"    */

 

The second variation makes the pointer clearer (note how the '*' is surrounded with white space to make it stand out), it reads better, and is consistent with function prototype arguments and with the layout in 6.?.?. It is, however, less common than the first layout and can be confusing if multiple variables are declared on one line.

6.15.6  Structure tags

A structure may be declared for future use at the same time the structure is defined:

 

struct SQUARE
{
    int     Width;
    int     Breadth;
} FirstSquare;

struct SQUARE   SecondSquare;

 

This is using the declaration for two purposes. It is more explicit and consistent to separate the definition and declaration:

 

struct SQUARE
{
    int     Width;
    int     Breadth;
};

struct SQUARE   FirstSquare;
struct SQUARE   SecondSquare;

 

6.15.7  Limited-value variables

Where a variable can only have a limited range of values, these should be declared as close as possible to the variable declaration:

 

struct EMPLOYEE
{
    int     EmpType;
    int     EmpSalary;
};

/*---- values for EmpType ----*/
#define WHITE_COLLAR  0
#define BLUE_COLLAR   1

/*---- values for EmpSalary ----*/
#define MAX_SALARY  1000
#define MIN_SALARY  30000

 

Note that declaring items with tags or typedef's enables the declaration and its constants to be placed together in a single header file.

 

<--Prev page | Next page -->

 

Site Menu

| Home | Top | Settings |

Quality: | Quality Toolbook | Tools of the Trade | Improvement Encyclopedia | Quality Articles | Being Creative | Being Persuasive |

And: | C Style (Book) | Stories | Articles | Bookstore | My Photos | About | Contact |

Settings: | Computer layout | Mobile layout | Small font | Medium font | Large font | Translate |

 

You can buy books here

More Kindle books:

And the big
paperback book


Look inside

 

Please help and share:

 

| Home | Top | Menu |

© Changing Works 2002-
Massive Content -- Maximum Speed