Chapter i. Language Nuts

This chapter describes the basic characteristics and elements of the C programming linguistic communication.

Characteristics of C

C is a general-purpose, procedural programming language. Dennis Ritchie first devised C in the 1970s at AT&T Bong Laboratories in Murray Hill, New Jersey, for the purpose of implementing the Unix operating arrangement and utilities with the greatest possible degree of independence from specific hardware platforms. The key characteristics of the C linguistic communication are the qualities that made it suitable for that purpose:

  • Source lawmaking portability

  • The ability to operate "shut to the machine"

  • Efficiency

Every bit a event, the developers of Unix were able to write almost of the operating system in C, leaving only a minimum of system-specific hardware manipulation to be coded in assembler.

C'due south ancestors are the typeless programming languages BCPL (the Basic Combined Programming Language), developed by Martin Richards; and B, a descendant of BCPL, developed by Ken Thompson. A new characteristic of C was its variety of information types : characters, numeric types, arrays, structures, and so on. Brian Kernighan and Dennis Ritchie published an official description of the C programming linguistic communication in 1978. As the offset de facto standard, their clarification is commonly referred to merely every bit "1000&R."[*] C owes its high degree of portability to a compact core language that contains few hardware-dependent elements. For example, the C linguistic communication proper has no file admission or dynamic memory management statements . In fact, there aren't even any statements for console input and output. Instead, the extensive standard C library provides the functions for all of these purposes.

This language design makes the C compiler relatively compact and like shooting fish in a barrel to port to new systems. Furthermore, once the compiler is running on a new system, yous tin can compile most of the functions in the standard library with no farther modification, because they are in turn written in portable C. Equally a result, C compilers are bachelor for practically every reckoner organisation.

Because C was expressly designed for organisation programming, it is inappreciably surprising that i of its major uses today is in programming embedded systems. At the same time, however, many developers use C as a portable, structured high-level linguistic communication to write programs such as powerful word processor, database, and graphics applications.

The Construction of C Programs

The procedural building blocks of a C program are functions , which tin invoke one some other. Every function in a well-designed program serves a specific purpose. The functions contain statements for the plan to execute sequentially, and statements can besides be grouped to course block statements , or blocks . As the programmer, y'all can use the ready-made functions in the standard library, or write your own whenever no standard function fulfills your intended purpose. In improver to the standard C library, at that place are many specialized libraries available, such as libraries of graphics functions. Withal, past using such nonstandard libraries, you limit the portability of your programme to those systems to which the libraries themselves take been ported.

Every C program must define at least one function of its own, with the special proper name main(): this is the beginning part invoked when the program starts. The main() role is the program's top level of control, and tin can call other functions as subroutines.

Instance one-i shows the structure of a simple, consummate C programme. Nosotros volition talk over the details of declarations, function calls, output streams and more elsewhere in this book. For now, nosotros are merely concerned with the general construction of the C source code. The plan in Instance 1-1 defines two functions, principal() and circularArea(). The main() function calls circularArea() to obtain the area of a circle with a given radius, and so calls the standard library office printf() to output the results in formatted strings on the console.

Example 1-1. A simple C plan

// circumvolve.c: Calculate and print the areas of circles  #include <stdio.h>                // Preprocessor directive  double circularArea( double r );  // Function declaration (prototype form)  int master()                        // Definition of main() begins {   double radius = 1.0, surface area = 0.0;    printf( "    Areas of Circles\n\n" );   printf( "     Radius          Area\n"           "-------------------------\n" );    area = circularArea( radius );   printf( "%10.1f     %10.2f\north", radius, area );    radius = 5.0;   expanse = circularArea( radius );   printf( "%10.1f     %x.2f\n", radius, expanse );    return 0; }  // The function circularArea() calculates the area of a circumvolve // Parameter:    The radius of the circle // Return value: The area of the circumvolve  double circularArea( double r )      // Definition of circularArea() begins {   const double pi = iii.1415926536;    // Pi is a abiding   return  pi * r * r; }

Output:

              Areas of Circles           Radius          Expanse     -------------------------            1.0           iii.14            5.0          78.54

Note that the compiler requires a prior declaration of each role chosen. The prototype of circularArea() in the third line of Example 1-1 provides the information needed to compile a statement that calls this function. The prototypes of standard library functions are constitute in standard header files. Considering the header file stdio.h contains the prototype of the printf() office, the preprocessor directive #include <stdio.h> declares the function indirectly past directing the compiler's preprocessor to insert the contents of that file. (Come across also the section "How the C Compiler Works," at the finish of this chapter.)

You may suit the functions defined in a program in whatsoever order. In Instance 1-1, we could just too have placed the function circularArea() earlier the part main(). If we had, and then the prototype declaration of circularArea() would be superfluous, because the definition of the function is also a proclamation.

Role definitions cannot be nested within i another: you tin ascertain a local variable within a function cake, but not a local office.

Source Files

The part definitions, global declarations and preprocessing directives make up the source code of a C program. For small programs, the source lawmaking is written in a unmarried source file. Larger C programs consist of several source files . Because the function definitions generally depend on preprocessor directives and global declarations, source files ordinarily have the post-obit internal construction:

  1. Preprocessor directives

  2. Global declarations

  3. Function definitions

C supports modular programming by allowing y'all to organize a program in equally many source and header files as desired, and to edit and compile them separately. Each source file generally contains functions that are logically related, such as the program's user interface functions. It is customary to label C source files with the filename suffix .c .

Examples ane-2 and 1-iii prove the same program every bit Example one-1, only divided into 2 source files.

Instance 1-2. The first source file, containing the main() part

// circle.c: Prints the areas of circles. // Uses circulararea.c for the math  #include <stdio.h> double circularArea( double r );  int main() {   /* ... As inExample 1-1 ... */ }

Case 1-3. The 2d source file, containing the circularArea() function

// circulararea.c: Calculates the areas of circles. // Chosen by main() in circle.c  double circularArea( double r ) {   /* ... As inExample ane-i ... */ }

When a plan consists of several source files, you need to declare the same functions and global variables, and ascertain the same macros and constants, in many of the files. These declarations and definitions thus form a sort of file header that is more or less constant throughout a program. For the sake of simplicity and consistency, you tin can write this data just one time in a divide header file , so reference the header file using an #include directive in each source code file. Header files are customarily identified by the filename suffix .h . A header file explicitly included in a C source file may in turn include other files.

Each C source file, together with all the header files included in it, makes up a translation unit . The compiler processes the contents of the translation unit sequentially, parsing the source lawmaking into tokens , its smallest semantic units, such as variable names and operators. See the department "Tokens," at the end of this chapter for more particular.

Whatsoever number of whitespace characters can occur between two successive tokens, allowing you a groovy deal of liberty in formatting the source code. At that place are no rules for line breaks or indenting, and you may use spaces, tabs, and blank lines liberally to format "homo-readable" source code. The preprocessor directives are slightly less flexible: a preprocessor directive must always appear on a line by itself, and no characters except spaces or tabs may precede the hash marker (#) that begins the line.

At that place are many different conventions and "firm styles" for source code formatting. Most of them include the post-obit common rules:

  • Start a new line for each new proclamation and statement.

  • Use indentation to reflect the nested construction of block statements.

Comments

You should use comments generously in the source code to document your C programs. There are two ways to insert a comment in C: block comments begin with /* and end with */, and line comments begin with // and end with the next new line character.

You can use the /* and */ delimiters to brainstorm and end comments within a line, and to enclose comments of several lines. For example, in the following part prototype, the ellipsis (...) signifies that the open up() function has a third, optional parameter. The comment explains the usage of the optional parameter:

              int open( const char *name, int mode, ... /* int permissions */ );

You can use // to insert comments that make full an entire line, or to write source code in a 2-column format, with plan code on the left and comments on the right:

              const double pi = 3.1415926536;     // Pi is constant

These line comments were officially added to the C language by the C99 standard, but most compilers already supported them even before C99. They are sometimes chosen "C++-way" comments, although they originated in C'southward precursor, BCPL.

Inside the quotation marks that delimit a graphic symbol constant or a cord literal, the characters /* and // do not start a annotate. For example, the post-obit statement contains no comments:

              printf( "Comments in C begin with /* or //.\n" );

The only thing that the preprocessor looks for in examining the characters in a comment is the stop of the annotate; thus it is non possible to nest block comments. Nonetheless, you can insert /* and */ to comment out office of a program that contains line comments:

              /* Temporarily removing two lines:       const double pi = 3.1415926536;     // Pi is abiding       expanse = pi * r * r                   // Calculate the surface area        Temporarily removed upwardly to here */

If you desire to comment out part of a program that contains block comments, you can use a conditional preprocessor directive (described in Chapter 14):

              #if 0       const double pi = iii.1415926536;     /* Pi is constant     */       area = pi * r * r                   /* Calculate the area */