1.1 Overview
Functions as program modules
Control flow within a program
The special function named main
Passing arguments to a function
Returning a value from a function
Writing functions that take a variable number of arguments
C distinguishes between function declarations, which show how a function is to be called, and function definitions, which provide the implementation detail. This chapter introduces the all-important distinction, and later chapters put the distinction to use in a variety of examples. The chapter also compares C functions with assembly-language blocks, which is helpful in clarifying how C source code compiles into machine-executable code.
Every general-purpose programming language has control structures such as tests and loops. Once again, short code examples introduce the basics of C’s principal control structures; later code examples expand and refine this first look at control structures.
1.2 The Function
Declaring and defining a function
The add2 example (see Listing 1-1) contrasts a function’s declaration with its definition. The declaration has no body of statements enclosed in braces, but the definition must have such a body. In a contrived example, the body could be empty, but the braces still would be required in the definition and absent from the declaration.
More on declaring and defining a function
Program structure may require that a function be declared and defined separately. For instance, if a program’s functions are divided among various source files, then a function defined in a given file would have to be declared in another file to be visible there. Examples are forthcoming.
As noted, a function’s body is enclosed in braces, and each statement within the body ends with a semicolon. Indentation makes source code easier to read but is otherwise insignificant—as is the placement of the braces. My habit is to put the opening brace after the argument list and the closing brace on its own line.
In a program, each function must be defined exactly once and with its own name, which rules out the name overloading (popular in languages such as Java) in which different functions share a name but differ in how they are invoked. A function can be declared as often as needed. As promised, an easy way of handling declared functions is forthcoming.
If a C function does not return a value, then void is used in place of a return data type. The term void, which is shorthand for no value, is technically not a data type in C; for instance, there are no variables of type void. By contrast, int is a data type. An int variable holds a signed integer value and so is able to represent negative and nonnegative values alike; the underlying implementation is almost certainly 32 bits in size and almost certainly uses the 2’s complement representation, which is clarified later.
There are various C standards, which relax some rules of what might be called orthodox C. Furthermore, some C compilers are more forgiving than others. In orthodox C , for example, there are no nested function definitions: one function cannot be defined inside another. Also, later standardizations of C extend the comment syntax from the slash-star opening and star-slash closing illustrated in Listing 1-1, and an until-end-of-line comment may be introduced with a double slash. To make compilation as simple as possible, my examples stick with orthodox C, avoiding constructs such as nested functions and double slashes for comments.
1.3 The Function main
In style, C is a procedural or imperative language, not an object-oriented or functional one. The program modules in a C program are functions, which have global scope or visibility by default. There is a way to restrict a function’s scope to the file in which the function is defined, as a later chapter explains. The functions in a C program can be distributed among arbitrarily many different source files, and a given source file can contain as many functions as desired.
An executable program with main and another function
This directive is used during the compilation process, with details to follow. The file stdio.h, with h for header, is an interface file that declares input/output functions such as printf , with the f for formatted. The angle brackets signal that stdio.h is located somewhere along the compiler’s search path (on Unix-like systems, in a directory such as /usr/include or /usr/local/include). The implementation of a standard function such as printf resides in a binary library (on Unix-like systems, in a directory such as /usr/lib or /usr/local/lib), which is linked to the program during the full compilation process.
Header files are the natural way to handle function declarations—but not function definitions. A header file such as stdio.h can be included wherever needed, and even multiple includes of the same header file, although inefficient, will work. However, if a header file contains function definitions, there is a danger. If such a file were included more than once in a program’s source files, this would break the rule that every function must be defined exactly once in a program. The sound practice is to use header files for function declarations, but never for function definitions.
at the command-line prompt and then hits the Return key, a system function in the exec family (e.g., execv) executes. This exec function then calls the main function in the add2 program, and main returns 0 to the exec function to signal normal termination (EXIT_SUCCESS). Were the add2 program to terminate abnormally, the main function might return the negative value -1 (EXIT_FAILURE). The symbolic constants EXIT_SUCCESS and EXIT_FAILURE are clarified later.
On Unix-like systems, or Windows with Cygwin installed ( https://cygwin.com ), there is a command-line utility man (short for manual) that contains documentation for the standard library functions and for utilities that often have the same name as a function: googling for man pages is a good start.
1.4 C Functions and Assembly Callable Blocks
The function construct is familiar to any programmer working in a modern language. In object-oriented languages , functions come in special forms such as the constructor and the method. Many languages, including object-oriented ones, now include anonymous or unnamed functions such as the lambdas added in object-oriented languages such as Java and C#, but available in Lisp since the 1950s. C functions are named.
Most languages follow the basic C syntax for functions, with some innovations along the way. The Go language , for example, allows a function to return multiple values explicitly. Functions are straightforward with respect to flow of control: one function calls another, and the called function normally returns to its caller. Information can be sent from the caller to the callee through arguments passed to the callee; information can be sent from the callee back to the caller through a return value. Even in C, which allows only a single return value at the syntax level, multiple values can be returned by returning an array or other aggregate structure. Additional tactics for returning multiple values are available, as shown later.
The traditional greeting program in C