@device(PostScript)
@make(report)
@DefineFont(HeadingFont,
	P=<RawFont "NewCenturySchlbkBoldItalic">,
	B=<RawFont "NewCenturySchlbkBold">,
	I=<RawFont "NewCenturySchlbkBoldItalic">,
	R=<RawFont "NewCenturySchlbkRoman">)
@Counter(Chapter,TitleEnv HD1,ContentsEnv tc3,Numbered [@1. ],
          IncrementedBy Use,Referenced [@1],Announced)
@Counter(Appendix,TitleEnv HD1,ContentsEnv tc3,Numbered [@I. ],
          IncrementedBy,Referenced [@I],Announced,Alias Chapter)
@Counter(Section,Within Chapter,TitleEnv HD2,ContentsEnv tc4,
          Numbered [@#@:.@1 ],Referenced [@#@:.@1],IncrementedBy
          Use,Announced)
@Counter(AppendixSection,Within Appendix,TitleEnv HD2,
          ContentsEnv tc4,
          Numbered [@#@:.@1 ],Referenced [@#@:.@1],IncrementedBy 
          Use,Announced)
@modify(CopyrightNotice, Fixed -1 inch, Flushright)
@Modify(Titlebox, Fixed 3.0 inches)
@Modify(hd1, below .2 inch, facecode B, size 20, spaces kept, pagebreak off)
@Modify(hd2, below .2 inch, facecode B, size 16, spaces kept)
@Modify(hd3, below .2 inch, facecode B, size 12, spaces kept)
@Modify(Description, Leftmargin +20, Indent -20,below 1 line, above 1 line)
@Modify(Tc3,Facecode B)
@Modify(Tc4,Facecode R)
@modify(example, size 9)
@Modify(Itemize,Above 1line,Below 1line)
@Modify(Insert,LeftMargin +2, RightMargin +2)
@Style(Font NewCenturySchoolBook, size 11)
@Style(Spacing 1.1, indent 0)
@Style(leftmargin 1.0inch)
@Style(justification no)
@Style(BottomMargin 1.5inch)
@Style(ChangeBarLocation Right)
@Style(ChangeBars=off)
@Style(Date "March 8, 1952")
@style(widowaction force)
@begin(Titlepage)
@Begin(Titlebox)
@begin(MajorHeading, size 36, Flushright)
Essential C
@end(Majorheading)
@end(titlebox)
@blankspace(3 lines)
@begin(flushright, size 14)
Bill Bryant
Sharon Belville
Documentation Group
MIT Project Athena
Revision B
@value(date)
@end(flushright)
@copyrightNotice(Massachusetts Institute of Technology)
@set(page=-1)
@end(titlepage)
@pageheading(immediate)
@pagefooting(left="MIT Project Athena",
center="@value(page)",right="Revision B, @value(date)")
@blankspace(5.5 inches)
@begin(format, size 10)

Revision B:  Bill Bryant, Sharon Belville, @value(date).  Removed
references to timesharing machines and IBM AT's.  Changed overall
"look" of document.

Revision A:  Bill Bryant, September 4, 1985.  Original document.
@end(format)
@newpage
@set(page=1)

@chapter(Introduction)

So you want to start programming in C.  This guide provides a tutorial
introduction to the language, and discusses its "conventional"
aspects.  You'll learn about:
@begin(itemize)
C's variables.

C's arithmetic operators.

C's looping and control constructs.

C functions.

The C compiler and its preprocessor.
@end(itemize)

This guide will teach you how to write, compile, and run simple, yet
useful, C programs.  When you have finished @p(Essential C), you
should be ready to learn about C's more advanced features.  If you
plan on becoming a bona fide C programmer, you will need to get a C
textbook.  See Appendix @ref(booklist) for a partial list of C books.

This guide assumes that you have had some, but not necessarily a lot,
of experience programming in another language.  You should be familiar
with concepts such as input/output, program variables and arrays, and
program looping.

@p(Essential C) also assumes that you know how to:
@begin(enumerate)
login to a workstation; and

use the Emacs editor to create and edit files.
@end(enumerate)

If you don't know these basics, you should first look through Athena's
@p(Athena Workstation) and @p(Essential Emacs) documents.

Note as well that this document approaches C programming from the Unix
perspective.

One final word before we begin: this document is relatively long.  If
you have never programmed in C before, don't expect to finish it in
one sitting.  You'll be much better off taking your time.

@chapter(The C "Programming Cycle")

C programs must be compiled before they can be run.  You will go
through four steps to get your first C programs up and running:

@begin(enumerate)
you write the program down on paper;

you enter the program into a computer file with a text editor (the
@i(Emacs) editor if you are on a workstation);

you compile the program with the C compiler @i(cc); and

you run the compiled program.
@end(enumerate)

The file you enter your program into is known as the program's
@b(source file).  Note that the filenames of all C source files must
end with @b(.c) (Our first C program discussed below is
@i[first@b(.c)]).  If you try to compile a program with a filename
that does not have this @i(.c) extension, the compiler will complain
that the file has a @i("bad magic number.")

When you send your source file to the compiler, @i(cc) goes through a
series of steps to translate the program into @b(machine code),
instructions the computer can understand.  When the compilation
process is finished, the machine code gets loaded in the program's
@b(a.out) file, the @b(executable) file you use to actually run the
program.  We'll delve into the details of compilation a little later;
let's take a look at a typical first C program.

@chapter(A Typical First C Program)

If you have looked through any of the introductory books on C, you
have already encountered the "Typical First C Program."  This program
prints some sort of message on your terminal screen and then retires.
In keeping with tradition, here is our version of the typical first C
program, @i(first.c): 
@begin(example) 

/* This program prints a message */ 
main() 
{
	printf("IHTFP!\n");
}
@end(example)

@section(Compiling and Running @i(first.c))

To see @i(first.c) in action,
compile it like this:
@begin(example)
host% @b(cc first.c)
@end(example)

where @r(host%) is the Unix shell prompt. 

Assuming that you have typed in the source file correctly, the
compiler will do its work silently.  When you've gotten the shell
prompt back, run the program by typing:

@begin(example)
host% @b(a.out)
@end(example)
(@i(a.out) is the default name of the program's executable file.)
The computer then prints the message on your screen,
then redisplays the shell prompt:
@begin(example)
IHTFP!
host%
@end(example)

See Appendix @ref(errors) for a discussion of @i(cc)'s error messages.

Now that you've seen @i(first.c) do its stuff,
let's take a closer look at its source code.

@section(Program Comments)

The first line of the program:
@begin(example)
/* This program prints a message */
@end(example)
is a program comment.
The C Compiler will ignore any text that you sandwich between
@b(/*) and @b(*/).

You can put comments anywhere in a C program, even on lines that also
have C code.  Don't be shy about using comments; when you begin
writing complex programs, they may be the only way that you'll be able
to remember what you were trying to accomplish when you wrote the
code.  If others have to examine your programs, they'll find your
comments indispensable.

@section(C Functions)

The program's next line:
@begin(example)
main()
@end(example)
marks the beginning of @i(first.c)'s @b[main()] function, the first of
many C functions you will encounter in your C programming adventures.
C functions are self-contained sections of code that are designed to
handle particular tasks.  C programs carry out their appointed tasks
by making calls to the appropriate functions.

Functions come in two flavors: @b(standard functions) (those that come
with the system), and @b(user-written functions) (those you get to
define on your own).  The standard functions are used to perform
"standard" programming tasks, tasks such as finding square roots, and
opening files.  You'll meet your first standard function shortly.

You can always tell a function by its parentheses; All functions have
them.  The parentheses are used to enclose the function's arguments,
and a function must have parentheses even if it doesn't have
arguments.

@section[The @i(main)() Function]

The @i(main)() function is an example of a user-written function.
All user-written functions have the same general format:
@begin(example)
functionname()
{
	statement;
	statement;
	    .
	    .
}
@end(example)

The opening brace, @b({), marks the beginning of the function's body,
the closing brace, @b(}), marks its end,
and the statements within the body constitute the function's definition.
@i(first.c's) @i(main)() function makes up the entire program:
@begin(example)
main()
{
	printf("IHTFP!\n");
}
@end(example)

The @i(main)() function is a special user-written function.
It is the only function that you (as a programmer)
can never call--you only get to define it.
That's because @i(main)() is the
function that controls the program's execution.
When you run @i(first.c),
the computer calls @i(main)() to locate the program's first statement,
and then executes all the statements in @i(main)()'s definition.
Every C program must have one and only one @i(main)() function.

The body of @i(first.c's) @i(main)() function is made up of only one
program statement,
the statement responsible for printing the message on your terminal screen:
@begin(example)
printf("IHTFP!\n");
@end(example)
In C, every program statement ends with a semi-colon;
if you forget to end a statement properly,
the compiler will generate an obscure error message and
will refuse to compile the program.

@section[The @i(printf)() Function]

This particular statement calls the @i(printf)() function.
@i(printf)() is a standard function,
one of several functions that C uses to handle progam output.
It is used to print text on the @i(standard output)--your terminal display.
(Unlike many languages,
C has no built-in Input/Output commands;
C programs rely on function calls to carry out all I/O.)

Since @i(printf)() is a function that prints,
it must be told what to print.
You do this by supplying arguments to the function.
In @i(first.c),
@i(printf)() is called with one argument,
the text string @b(IHTFP!).
This text string is often referred to as a @i(control string).
Make sure you enclose all control strings in double quotes;
the double quotes tell the computer to treat the
text as a @i(string constant).
Note that @i(printf)() does not print the double quotes
on your terminal screen.

@section(The @i(Newline) Character and Other Escape Sequences)

You may be puzzled about the @b(\)@i(n).
It is the @b(newline character).
When @i(printf)() encounters
this character it advances the cursor to the next line of the display.
The newline character is one of a handful of @b(escape sequences)
used to represent invisible and hard-to-get characters.
Others include @b(\)@i(t) for tab,
@b(\)@i(b) for backspace,
@b(\)@i(") for double quote,
and @b(\\) for backslash.
If you feel like experimenting,
remove the @b(\)@i(n) from @i(first.c),
recompile the program,
run it and see what happens.

@section(C's Standard Libraries and the C Compiler)

All of C's standard functions are
stored in the system's libraries.
A @b(library) is a file that contains a collection of precompiled functions.
C's functions are stored in several libraries,
with functions catalogued by type.
The I/O functions are kept in an I/O library,
the math functions are kept in the math library,
and so on.
The @i(printf)() function,
for example,
is a member of the I/O library.
The I/O library is grouped together with several other important libraries
in the @i(/lib/libc.a) file.
The math library is kept in the @i(/usr/lib/libm.a) file.

As the compiler compiles your program,
it checks for functions that the program calls but does not define.
When the rest of the program has been translated into machine code,
the compiler uses the Unix @i(Link Editor) (@i(ld)) to search
the libraries in @i(/lib/libc.a) for the undefined functions.
When @i(ld) finds the missing functions,
it copies their definitions directly into the program.
The program is then @i(loaded) into the executable
file and is then ready to run.
The process of searching for and copying functions is referred to
as @b(linking).

@chapter(The Second Program)

Let's move on to a slightly more complicated program,
one that uses variables and does some simple calculations.
The program in question,
@i(bridgecon.c),
converts the length of the Harvard Bridge
(also known as the Massachusetts Avenue Bridge) from smoots to miles.
According to the most descriminating of sources,
the Harvard Bridge is 364.4 smoots and an ear long,
but for the purposes of this program,
we'll round up to 365 smoots.
And we'll guesstimate that a smoot equals five feet, eight inches--
5.667 feet.
Here's the program:

@begin(example)
/*
 *  	This program converts length of the
 *  	Harvard Bridge from smoots to miles 
 */

main()
{
    	int smoots;
    	float miles, mi_per_smoot;

    	smoots = 365;
    	mi_per_smoot = 5.667/5280;
    	miles = mi_per_smoot * smoots;
    	printf("How long is the Harvard Bridge?\n");
    	printf("Almost %d smoots, or about %f miles.\n", smoots, miles);
}
@end(example)

When you compile @i(bridgecon.c) and run the resulting @i(a.out)
file,
the program will print the following message:
@begin(example)
How long is the Harvard Bridge?
About 365 smoots, or 0.391753 miles long.
@end(example)
Now for a closer look at @i(bridgecon.c).

@section(Variables and Variable Declaration)

These two statements:
@begin(example)
	int smoots;
	float miles, mi_per_smoot;
@end(example)
are variable declarations; they tell the compiler the names and types
of the program's variables.  The words @b(int) and @b(float) are C
@b(keywords)--words reserved by C.  You can't use keywords as
variables or function names.  Variables declared as @i(int) are used
to hold integer values, and variables declared as @i(float) are used
to hold real (floating point) numbers.

C lets you use letters and numbers to make up variable names, but the
name's first character must be a letter.  C considers the underscore
character, "@b(_)", a letter.

Notice that we have included a blank line to set off the variable
declarations from the rest of the program.  The C compiler ignores
spaces and blank lines, so use space to make your programs easier to
read.

@section(The Assignment Statement)

The following is a C @b(assignment statement).
@begin(example)
smoots = 365;
@end(example)
In English it might be rendered "give the variable @i(smoots) the
value 365."  The @b(=) sign is known as the @b(assignment operator).
Sometimes programmers get the assignment operator mixed up with the
@b(equality operator), @b(==), the operator that you use to test
@i(whether or not) the value stored in a variable equals the value of
a certain number or expression.  Keep in mind that @b(=) does not
equal @b(==).  We'll have more to say about the @b(==) operator in
Section @ref(ifelse).

Note that we declared @i(smoots) as an @i(int) variable type,
and here we are giving it the value of 365.
What would have happened had we assigned a floating point value
to this @i(int) variable.
@begin(example)
smoots = 364.4;
@end(example)
The compiler would let us compile the program, but when running the
program, the computer would assign the variable the number 364, and
not 364.4.  An @i(int) variable will always be assigned the integer
portion of a number or expression.  In most instances you should avoid
assigning floating point numbers to @i(int) variables.
@begin(example)
mi_per_smoot = 5.667/5280;
miles = mi_per_smoot * smoots;
@end(example)

These statements assign their respective variables the values of the
expressions; the @b(/) character is C's division operator, and @b(*)
is C's multiplication operator.

@section[Calling @i(printf)() with Multiple Arguments]

@begin(example)
printf("How long is the Harvard Bridge?\n");
printf("Almost %d smoots, or about %f miles.\n", smoots, miles);
@end(example)

Here is the @i(printf)() function again, this time used in a more
sophisticated fashion.  The second statement calls @i(printf)() with
three arguments: the string constant to be printed, and the variables
@i(smoots) and @i(miles).  When @i(printf)() prints the string, it
replaces the two @i(conversion specifiers), @b(%d) and @b(%f), with
the values of the two variables.  The @b(%d) tells @i(printf)() to
print @i(smoots') value in @i(@b(d)ecimal integer) format, and the
@b(%f) tells the function to print @i(miles') value in @i(@b(f)loating
point) format.

@section(The C Compiler's Preprocessor)

As a short, almost do-nothing program, @i(bridgecon.c) does what we
want.  But it also has some questionable features in it--features that
don't seem serious in a short program, but can cause problems as you
start writing @i(real) C programs.

In particular, let's reexamine the following statement:
@begin(example)
mi_per_smoot = 5.667/5280;
@end(example)
Pretend that this statement is buried in the middle of a much larger
program, and you need to understand the significance of 5.667/5280.
These numbers do not, in themselves, convey the fact that they are
conversion factors--that 5.667 is the number of feet per smoot, and
5280 is the number of feet per mile.  In informal programming jargon,
these are called @i(magic numbers).  "@i(Magic)" because who knows
where they came from?  (Note that these magic numbers have nothing to
do with the magic number that @i(cc) complains about when you forget
the @i(.c) extension on a source file name).

In the following version of @i(bridgecon.c),
we have eradicated the magic numbers and the
resulting program is much easier to understand.

@begin(example)
/*
 *  	This program converts length of the
 *  	Harvard Bridge from smoots to miles 
 */

#define FEET_PER_SMOOT 5.667
#define FEET_PER_MILE 5280
#define SMOOTS 365

main()
{
    float  miles, mi_per_smoot;

    mi_per_smoot = FEET_PER_SMOOT/FEET_PER_MILE;
    miles = mi_per_smoot * SMOOTS;
    printf("How long is the Harvard Bridge?\n");
    printf("Almost %d smoots, or about %f miles.\n", SMOOTS, miles);
}
@end(example)


@c(FEET_PER_SMOOT),
@c(FEET_PER_MILE),
and @c(SMOOTS) are @b(symbolic constants).
Once we have defined them,
we can use them in place of the magic numbers they stand for.
Note however that the @i(#define) statements are not part of
the C language--they are commands to the C compiler's
@b(preprocessor).

Before the compiler begins working on program,
its preprocessor scans the source file to see if any of the program's lines
begin with the @b(#) sign
(@b(#) indicates a preprocessor command).
In the case of this program,
the @i(#defines) tell the preprocessor to associate the
numbers @b(5.667), @b(5280), and @b(365) with the
symbolic constants @c(FEET_PER_SMOOT),
@c(FEET_PER_MILE), and @c(SMOOTS) respectively.
The preprocessor then searches through the rest of the program
and replaces each symbolic constant with its corresponding number.
The compiler won't begin compiling code until this replacement process
is complete.

In addition to solving the @i(magic number) problem,
@i(#define) statements let you change the value of a program's
constants in one place.
Suppose,
for instance,
that you discovered that the value for @c(FEET_PER_SMOOT),
@b(5.667), was incorrect.
You could correct the value in the @i(#define) statement and
rest assured that the value will be right for the entire program.
In large programs,
@i(#define) statements are not just a convenience,
they are a necessity.

@section(Header Files and the @i(#include) Statement)

The preprocessor also gives you the option of putting your @i(#define)
statements into a file that can be inserted into the program at
compile time.
Files such as this are referred to as a @b(header files),
and their names,
by convention,
end with @i(.h).

Suppose,
for instance,
that you wanted to place the @i(#define) statements used above
in a header file called @i(smootstuff.h).
You could then use the preprocessor's @i(#include) command as follows:

@begin(example)
/*
 *  	This program converts length of the
 *  	Harvard Bridge from smoots to miles 
 */

#include "smootstuff.h"

main()
{
    float  miles, mi_per_smoot;

    mi_per_smoot = FEET_PER_SMOOT/FEET_PER_MILE;
    miles = mi_per_smoot * SMOOTS;
    printf("How long is the Harvard Bridge?\n");
    printf("Almost %d smoots, or about %f miles.\n", SMOOTS, miles);
}
@end(example)

When you compile this version of the program,
the preprocessor will search your @b(current directory) for @i(smootstuff.h).
When it finds the file,
the preprocessor will replace the @i(#include) statement with the file's contents.
The preprocessor will then examine the @i(#define) statements,
and finish up by replacing the symbolic constants
with their corresponding numbers.

At this point,
you may be wondering why anyone would bother using header files.
What's so tough about adding a handful of @i(#define) statements at
the top of a program?
As you gain experience with C,
you may find that you habitually use the same sets of symbolic constants
for various programs.
If you set up standard header files,
you can use a single @i(#include) statement to bring them in to
all your programs.

You should keep a couple of things in mind when you add preprocessor
statements to your programs.
Each statement must begin in the program's first column so that the
preprocessor can find it.
Also note that symbolic constants,
by convention,
are composed of uppercase letters.
This makes them easy to distinguish from program variables,
and easy to locate in general.

@chapter(C's Other Arithmetic Operators)

The @i(bridgecon.c) program introduced you to two of C's
arithmetic operators: the division operator @b(/),
and the multiplication operator @b(*).
What about other operators?

As you might expect,
the @b(+) sign is C's addition operator,
and the @b(-) sign is C's subtraction operator.
You can also use the @b(-) sign to make a variable (or
other value) negative.

C also furnishes @i(increment) and @i(decrement) operators,
@b(++) and @b(--) respectively.
You use @b(++) to increase a variable's value by 1,
and @b(--) to decrease its value by 1.
In other words,
instead of writing this:
@begin(example)
towers = towers + 1;
@end(example)
You can write this:
@begin(example)
++ towers;
@end (example)
We'll talk more about these operators in our discussion of C's @i(for)
loop, in Section @ref(forloop).

As mentioned earlier, C has many features that let you write compact
source code.  Included among these are the @i(operator-assignment)
operators (operators that do both an operation and an assignment):
@begin(example)
+=	-=	*=	/=
@end(example)
Curious looking beasts, huh?
They let you condense a program statement like this:
@begin(example)
cows = cows + calves;
@end(example)
to this:
@begin(example)
cows += calves;
@end(example)
Note that the operators treat the right-hand expression as
though it were enclosed in parentheses.
In other words,
the statement
@begin(example)
cash *= balance - interest;
@end(example)
is shorthand for this:
@begin(example)
cash = cash * (balance - interest);
@end(example)
and not this:
@begin(example)
cash = (cash * balance) - interest;
@end(example)

@chapter(Renaming @i[a.out] with @i[cc]'s @i[-o] Option)

Each time you use @i[cc], the compiler creates a @i[a.out] file.  If
an @i(a.out) file already exists, the new one will overwrite the old
one.  This can be inconvenient if you want to work with more than one
executable program at a time.  In situations such as these, you have
two choices: use the Unix @i[mv] command to change the current
@i[a.out's] name, or use the compiler's @i[-o] option to give the
executable program a name other than @i[a.out].

The @i[-o] option is used as follows:

@Begin(Example)
host% @b(cc -o @i(executefile sourcefile.c))
@End(Example)
where @i[executefile] is the name you want to give the executable
version of the program.  Suppose, for instance, that you wanted to
compile @i[bridgecon.c] into an output file called @i[bridgecon].
Compile it this way:

@Begin(Example)
host% @b(cc -o bridgecon bridgecon.c)
@End(Example)
The compiler will create the executable file @i[bridgecon], and will
leave any current @i[a.out] file undisturbed.  (It is a Unix
convention to use the source file's name, minus the @i(.c) extension
as the name of the program's executable file.)

@chapter(The Third C Program: Character Data)
@label(7)
Traditionally,
new C programmers have learned a lot about the language
by writing and experimenting with programs that
manipulate characters.
And so we come to our next program, @i(echo.c).
This program prompts you to enter keyboard characters,
and then reprints (echoes) the characters on your display
when you press the @c[RETURN] key:

@begin(example)
/* 
 *	This program echoes characters
 */

main()
{
	int c;

						/*  Instruct and prompt
						 *  the user
						 */

    	printf("Enter characters, one at at time if you like,\n");
    	printf("or in strings.  Enter X when you want to stop.\n");

			/* Get the first character */
		
	c = getchar();

			/*
		 	 * 	Test c for terminating character X,
	         	 * 	loop until X is read
	         	 */

	while (c != 'X')
	{
		putchar(c);    /* Echo the character */
		c = getchar(); /* Get the next character */
	}
}
@end(example)

@i(echo.c) introduces the C standard functions @i(getchar)() and
@i(putchar)(), mainstay functions for most character-related programs.
@i(getchar)() and @i(putchar)() handle character input and output,
respectively, one character at a time.  For instance, the following
statement:
@begin(example)
c = getchar();
@end(example)
uses the @i[getchar]() function to assign an input character to the
variable @i(c).  The statement
@begin(example)
putchar(c);
@end(example)

prints the character stored in @i(c) on your terminal screen.
(Actually, @i[putchar]() outputs the character to a buffer, a
temporary storage space in the computer; when you press the @c[RETURN]
key, the contents of the buffer get printed on your display.)

@section(The Integer Nature of Character Data)
@label(7.1)
Notice that we have declared @i(c) to be of type @i(int).
This might strike you as curious seeing that we are
using the variable to store a character value.
It all has to do with the fact that the computer stores
characters as small integer values.

For instance, the @c[ASCII] character @b(a) is stored internally as
the integer @b(97), the character @b(b) is stored as @b(98), and so
on.  (@c[ASCII], which stands for American Standard Code for
Information Interchange, is the character set used by Athena
computers.)

When the @i(getchar)() function gets a character from your keyboard,
it returns that character's corresponding integer to the program.
When the @i(putchar)() function is called to print a character, it
converts the integer value to its corresponding character.

The C language also lets you declare variables as having the type
@b(char), but for reasons that we will go into presently (Section
@ref(7.4)), you should declare a variable as @i(char) only when you are
declaring a @i(character array).  We'll discuss @i(character arrays)
in Section @ref(11).

@section(The @i(while) Loop Construct)

In its general form,
the @i(while) construct looks like this:

@begin(example)
	while (expression)
	{
		statement;
		    .
		    .
	}
@end(example)
The construct works as follows:

@begin(itemize)

The computer tests the expression.

If the expression is true,
the computer executes the subsequent block of statements
and then tests the expression again.

If the expression is false,
the computer skips past the @i(while's) statement block
to the next statement in the program.
@end(itemize)

Let's see how our @i(while) loop:
@begin(example)
	while (c != 'X')
	{
		putchar(c);
		c = getchar();
	}
@end(example)
measures up to the general form.
When the computer encounters the @i(while),
it tests the validity of the expression:
@begin(example)
c != 'X'
@end(example)
In C, @b(!=) translates to @i(does not equal).
As long as the value of @i(c) is not the character @i(X),
the expression is true,
and the @i(while's) statements get executed.
That is,
the @i(putchar)() function echoes the value of @i(c),
then @i(getchar)() brings in a new character.
When the computer has executed the loop's last statement,
it returns to the top of the loop and retests the expression.
The loop terminates when the user signals the end of input
by entering an @i(X);
when the loop terminates,
the program terminates.

@section(@i(EOF) and @i(stdio.h))

As a first cut at an @i(echo)-type program, @i(echo.c) works well
enough, but it could stand some improvement.  A program like this
should be capable of echoing the entire keyboard set without having to
reserve an arbitrary character to signal the end of input.  This
"end-of-input" problem crops up in many instances, and most C programs
solve it by testing incoming characters for the @b(EOF) value.

@i(EOF) is a symbolic constant that stands for @b(E)nd @b(O)f
@b(F)ile, and it corresponds to the @b(CTRL-d) sequence: when you
press @i(CTRL-d) while inputting data, you signal the end of input.


Like the symbolic constants we met earlier, you specify @i(EOF's)
value with a preprocessor @i(#define) statement.  The problem is, that
value is not the same for all computers.  On some computers you would
define the constant like this:
@begin(example)
#define EOF -1
@end(example)
On others you would define it like this:
@begin(example)
#define EOF 0
@end(example)
Fortunately,
all C programming environments have a standard header file
that contains the appropriate @i(EOF) definition.
This header file goes by the name of @b(stdio.h)
(@b(st)andar@b(d) @b(i)nput/@b(o)utput @b(h)eader file).
@i(Stdio.h) is one of several standard header files available
to C programmers;
they are grouped together in the system's @i(/usr/include) directory.
You can use the preprocessor's @i(#include) command to
insert the @i(stdio.h) file into your program,
but since @i(stdio.h) is a system header file,
you use @i(#include) with a slightly different syntax.
@begin(example)
#include <stdio.h>
@end(example)
The "pointy" brackets, (@b[< >]),
tell the preprocessor to search the @i(/usr/include) directory
for the specified header file.
Note that
you will want to include @i(stdio.h) in all programs that use standard
I/O functions.

Here's a version of @i(echo.c) that uses @i(EOF) and
the appropriate @i(#include) statement:

@begin(example)
/*
 *	This program echoes characters
 */

#include <stdio.h>
main()
{
	int c;

					/*
					 *  Instruct and prompt
					 *  the user
					 */

	printf("Enter characters, one at at time if you like,\n");
	printf("or in strings.  Enter Ctrl-d when you want to stop.\n");

			/* Get the first character */

	c = getchar();

			/*
		 	 * Test the character for the end of input,
   		 	 * and loop until end of input is read
		 	 */

	while (c != EOF)
	{
		putchar(c);	/* Echo the character */
		c = getchar();	/* Get next character */

	}
}
@end(example)

@section(@i(char) Types and EOF Don't Mix)
@label(7.4)
As was mentioned in Section @ref(7.1), the computer stores character data as
small integer values.  If you declare a variable as having the type
@i(char) as opposed to the type @i(int), the computer restricts the
range of integer values that variable can hold.  The @i(EOF) value is
also an integer, but its value doesn't fall in the range of acceptable
@i(char) integers.  Some computers throw fits when you try to test a
@i(char) variable for a non-char value.  Therefore, whenever you test
a variable for the @i(EOF) value, declare the variable as an @i(int)
type, and not a @i(char) type.

Under what circumatances would you want to declare a variable as
@i(char) and not @i(int)?  When you are declaring a @i(character
array).  We will elaborate on this topic in Section @ref(11.1).

@section(Another Condensing Trick)

Now @i(echo.c) has the right functionality,
but it isn't quite as refined as it could be;
you could tighten the program up by employing
another of C's "condensing" features.
Just as an arithmetic operator
such as @b(+) returns a value when used in an expression
(namely the sum of its two operands),
the assignment operator @b(=) returns a value--the value being assigned to
the variable.
This value can in turn be used as part of another expression;
you can assign a value to a variable,
and test that value in the same expression.
You can, for instance,
condense this:
@begin(example)
c = getchar();
while (c != EOF)
@end(example)
to this:
@begin(example)
while ((c = getchar()) != EOF)
@end(example)
(Note that we enclosed the expression "c = getchar()" in parentheses;
the expression won't work properly unless you do this.)

Using this condensing trick,
@i(echo.c) now looks like this:
@begin(example)
/* 
 *	This program echoes characters
 */

#include <stdio.h>

main()
{
	int c;

					/*
					 * Instruct and prompt
					 * the user
					 */

    	printf("Enter characters, one at at time if you like,\n");
    	printf("or in strings.  Enter Ctrl-d when you want to stop.\n");

				/*
				 * Read character and loop
				 * until end of input is read
				 */

	while ((c = getchar()) != EOF)
	{
		putchar(c);	/* Echo character */

	}
}

@end(example)
If you compile and run this version of the program,
you will find that it operates just like the original version,
except that you halt its process by entering @i(CTRL-d)
instead of @i(X).

@chapter(The Fourth Program: @i(if-else))
@label(ifelse)
Let's move on to a more sophisticated character-manipulating program.
@i(Parse.c) is a simple text parser;
it breaks input lines into single "words" by testing for space,
tab, and newline characters.
This program introduces the decision-making construction @i(if-else),
the equality operator @b(==),
and the logic operator @b(||).

@begin(example)
/*
 * 	This program takes input and writes
 *  	single words on separate lines
 */

#include <stdio.h>

main()
{
	int c;

			 	/*
			 	 * Take input, a character at a time,
			 	 * until EOF
			 	 */

	while ((c = getchar()) != EOF)
	{
	 				/* If c is a space, tab, or newline-- */

		if (c == '\n' || c == ' ' || c == '\t')
		{

		 			/* Parse the word by printing a newline */
			putchar('\n');
		}

				       /* Otherwise . . . */

		else
		{
			 putchar(c);  /* Print the character */
		}
	}
}
@end(example)

@i(If-else) is the most general
of C's decision-making constructs.
(The others, not discussed in this document, are the @i(switch)
construct and the @b(?) operator.)
In its general form,
@i(if-else) looks like this:
@begin(example)
if (expression)
{
	statement;
	   .
	   .
}
else
{
	statement;
	   .
	   .
}
@end(example)
Note that the @i(else) part of the construct is optional;
you can test for and act on a condition without having to provide
alternative actions.
The  @i(if-else) construct works as follows:
@begin(itemize)
The computer tests the expression.

If the expression is true, the computer executes the following block
of statements and then skips over the @i(else) statement block to the
next statement in the program.

If the expression is false and the construct has an @i(else) part,
the computer executes the block of statements associated
with the @i(else) and then continues with the rest of the program.

If the expression is false and the construct does not have an @i(else)
part, the computer skips the statements in the @i(if) block and moves
to the next statement in the program.

@end(itemize)

The @i(if) construct used in @i(parse.c) tests the following expression:
@begin(example)
c == '\n' || c == ' ' || c == '\t'
@end(example)
The @b(or) operator, @b(||),
is one of  C's two @b(logical connectives);
the @b(and) operator @b(&&) is the other.
(You'll get to see @b(&&) in action before we get through.)

An English translation of the expression reads as follows:
"the variable @i(c) is equal to the @i(newline) character,
or @i(c) is equal to the @i(space) character,
or @i(c) is equal to @i(tab) character."
When you use expressions like this,
you must always test the variable for each value explicitly.
The following expression,
for instance,
doesn't work:
@begin(example)
c == '\n' || ' ' || '\t'
@end(example)

As mentioned earlier,
it isn't hard to mix up the @i(equality) operator, @b(==),
with the assignment operator, @b(=),
yet the two are entirely different.
Unfortunately,
the compiler won't care if you mistakenly use one in place of the other.
@i(Cc) will compile the code without a hitch,
and you will be left with a program that behaves mysteriously.

@section(Nested @i(if)'s)

You can use the @i(if-else) construct to make multi-way decisions.
Suppose,
for instance,
that you wanted @i(parse.c) to specify the types of space it encounters
as it parses words.
You could use @i(if-else) as follows:
@begin(example)
if (c == '\n')
{
	printf("newline\n");
}
else if (c == ' ')
{
	printf("space\n");
}
else if (c == '\t')
{
	printf("tab\n");
}
else
{
	putchar(c);
}
@end(example)

In this situation,
you should probably use a @i(switch) statement instead of the
nested @i(if)s.

@chapter(The Fifth Program: @i(for) loops and Functions)
@label(forloop)
The next program, @i(factorial.c), prints the values of all the
factorials between 1 and 10.  @i(Factorial.c) is the first program we
have dealt with that uses more than one user-written function.  The
program's @i(main)() function controls execution, but @i(main)() makes
a call to the @i(factorial)() function to perform the calculations.
@begin(example)
/*
 *	This program tests the factorial function,
 *	and in the process, prints the first ten factorials
 */

main() 
{
	int n, fac;
	int factorial();

			/*
			 * Set n equal to 1; loop until n is greater
			 * than 10, each time incrementing n by 1
			 */

   	for (n = 1; n <= 10; ++n)
   	{   
		fac = factorial(n); 	  /* Set fac to factorial of n */
		printf("%d! equals %d.\n", n, fac);  /* Print n and fac */
   	}
}

 /* 
  * This function that calculates factorials
  */

int factorial(number)
    int number;
    {
        int n, answer;

					/*
				 	 * Set n and answer to 1,
				 	 * loop until n is greater
				 	 * than number, incrementing
				 	 * n by 1 each time.
				 	 */

	for (n = answer = 1; n <= number; ++n)
	{
		answer *= n;	/* Multiply answer by n */
	}

	return(answer);         /* Return the factorial of number */
    }
@end(example)
@i(factorial.c) uses the @i(for) loop construct to do much of its work.
In its general form,
@i(for) looks like this:
@begin(example)
for (expression1; expression2; expression3)
{
	statement;
	    .
	    .
}
@end(example)
The typical @i(for) loop uses the first expression to initialize an
@i(index) variable, the second expression to test that variable for a
loop-ending condition, and the third expression to increment the
variable for each trip through the loop.  The @i(for) loop in the
@i(main)() function of @i(factorial.c) works in just that way:
@begin(itemize)
The variable @i(n) is initialized to 1.

@i(n) is then tested to see if it is less than or equal to 10 (@b(<=)
is C's less-than-or-equal-to operator).  @i(n) is less than 10, so the
computer begins executing the statements in the loop.

@i(n) is used as an argument to the @i(factorial)() function.

When the @i(printf)() statement in the loop has been executed, @i(n)
is incremented by one.  (Remember our brief mention of the @b(++)
operator?)

@i(n) is then tested to see if it is still less than or equal to 10
and if @i(n) satisfies the condition, the computer reexecutes the
loop's statements.

When @i(n) becomes greater than ten, the computer skips over @i(for's)
statements to the next statement in the program.  (In this instance,
there are no more statements after the loop; the program terminates
when the loop does.)
@end(itemize)
The @i(for) loop used in the @i(factorial)() function works
similarly,
though in this instance we have used the construct's first
expression to initialize two variables instead of one.

@section(Defining Functions)

In its general form,
a user-defined function looks like this:
@begin(example)
@i(type) functionname(@i(argument list))
	 @i(argument declarations);
		     .
		     .
	
	{
		function declarations;
			 .
			 .

		function statements;
			 .
			 .
	}
@end(example)

Here's how our @i(factorial)() function matches up:
@begin(example)
int factorial(number)
    int number;
    {
        int n, answer;

	for (n = answer = 1; n <= number; ++n)
	{
		answer *= n;
	}

	return(answer);
    }
@end(example)

The @i(type) specifier indicates what type of value the function
returns when it finishes executing.
This specifier is optional:
if you don't specify a type,
the compiler will assume that the function returns an @i(int) value.
Therefore,
we didn't have to specify @i(factorial)()'s type,
because the default is @i(int).
If the function had been written to return a floating point value,
we would have had to specify it as a @i(float).

Note as well that we declared @i(factorial)()'s type in the @i(main)()
function of the program..
Because that type is @i(int),
we didn't really have to do this,
but if the type had been something else,
the compiler would have squawked if we hadn't declared it properly.

Some functions take arguments and some don't,
so the @i(argument list) is optional as well.
@i(Factorial)() takes one argument--the variable @i(number).
If the function you are defining takes more than one argument,
use commas to separate them:
@begin(example)
drift(angle, wind, current)
@end(example)

Functions that take arguments must declare the arguments' types.
In the case of @i(factorial)(),
we declared @i(number) as an @i(int).

The rest of the function's definition corresponds directly
to the form we have used in defining @i(main)()s:
the function's body is enclosed in braces
and its variables must be declared before being used in the
function's statements.

@section(Variables in Functions: Scope)

As you may have noticed while perusing @i(factorial.c),
@i(main)() and @i(factorial)() both use a variable @i(n).
Are the two variables in fact one and the same?
No.
In C,
the variables declared in each function are @i(local)
to that function and in no way interfere with variables
declared in other functions.
The two @i(n)'s used in @i(factorial.c) are stored in
separate locations within the computer,
and hence,
have nothing to do with each other.

When a function uses one of its variables
as an argument in a function call,
the function being called gets a copy of the variable,
not the variable itself.
For instance,
when @i(factorial.c)'s @i(main)() function uses its @i(n)
as an argument to the @i(factorial)() function,
@i(n)'s value is copied to @i(factorial)()'s variable
@i(number).
@i(number) and @i(n) are not the same variable,
and if the @i(factorial)() function changed the value of
@i(number),
@i(n) would retain its value.

Does C provide a means by which you can use a function
to directly change the value of a variable in another function?
Yes,
through the use of @i(pointers).
A discussion of pointers is beyond the scope of this document.
If you want to learn the details,
locate a book on C,
pull up a chair,
and start reading.
(See Appendix @ref(booklist) for a list of recommended C books.)

@section(Using @i(cc) to Compile Multiple Source Files)

@i(Factorial.c) demonstrates the strength of breaking
programs into functions.
The @i(factorial)() function stands on its own as a useful piece of code.
If you wanted to,
you could put its source code into a separate file and
add it into any program at compile time.
Suppose that you put the function's source in a file called
@i(factor.c).
You would use @i(cc) as follows to compile the function with
another program:
@begin(example)
host% @b(cc @i(mainprog.c) factor.c)
@end(example)
where @i(mainprog.c) is the name of the program that calls @i(factor.c).
The compiler compiles both @i(modules) and loads them together
into one executable file.

@chapter(The Sixth Program: the Math Library)

Our next program, @i(hyp_test.c),
tests the user-written function @i(hyp)().
This function uses the lengths of a right triangle's
two legs to calculate the its hypotenuse.

The @i(hyp)() function uses the standard function @i(sqrt)() to
perform the actual calculation.
Obviously the @i(sqrt)() function is going to return a floating point number
rather than an integer,
and that means that @i(hyp)() will return a floating point number as well.

Note however,
that @i(sqrt)() is designed to return a @i(double precision) floating
point number.
Double precision values are more accurate than their @i(float)
counterparts.
Variables and functions that deal with them must be declared as
@i(double) instead of @i(float).
Here's the program:

@begin(example)
/*
 *	This program tests the hyp() function
 */

#include <stdio.h>
#include <math.h>

main()
{
   	double  hyp();        /* Declare the hyp() function as double */
   	float a = 7, b = 12;  /* Declare and initialize triangle's legs */

   	printf("The legs of the triangle are 7, and 12\n");
   	printf("The hypotenuse is %f.\n", hyp(a, b));
}

/*
 * 	This function calculates the length of
 *	a right triangle's hypotenuse given
 *	the triangles legs
 */

double hyp(leg1, leg2)
double leg1, leg2;                   /* Declare hyp's arguments */

{
	double hypotenuse;

   	hypotenuse = sqrt((leg1 * leg1) + (leg2 * leg2)); /* calculate answer */
   	return (hypotenuse);
}
@end(example)

Note that although we declared @i(hyp)() as a @i(double) in the
program's @i(main)(),
we did not bother to declare @i(sqrt)() in the definition of @i(hyp)().
That is because the @i(math.h) header file,
brought into the program by a preprocessor @i(#include) command,
makes the declaration for us.
@i(Math.h) contains declarations for all the math functions
contained in C's math library.
Consult Section 3M of the Athena @p(Unix Functions Manual) for
more information on the math library's functions.
(Type:  @i(man 3m intro).)

If you try to compile this program in the same manner that you
compiled the previous programs, you'll see @i(cc) spit out the
following error message:
@begin(example)
Undefined:
_sqrt
@end(example)
The message, which is actually a message from the Link Editor, @i(ld),
indicates that @i(ld) was unable to locate the @i(sqrt)() function in
any of the libraries it routinely searches.  That's because @i(ld)
does not routinely search the math library.  You can get @i(ld) to
@i(link) to the library by using the @i(-l) option when compiling the
program with @i(cc):

@begin(example)
host% @b(cc hyp_test.c  -lm)
@end(example)

The @i(-l) option tells @i(ld) to search through the indicated library
for missing functions.  When you use the option you must give the
abbreviation of the library you want to link to.  The math library is
kept in the @i(/usr/lib/libm.a) file, and its abbreviation is @i(m).
Do not insert a space between the @i(-l) and the abbreviation.

Note that if you use the @i(-l) option with any of @i(cc's) other
options, you must use @i(-l) last.  For instance, suppose you want to
compile @i(hyp_test.c) and use the @i(-o) option to put the executable
program into a file called @i(hyp_test).  You would use @i(cc) as
follows:

@begin(example)
host% @b(cc -o  hyp_test  hyp_test.c  -lm)
@end(example)

@chapter(The Last Essential Program: Character Arrays)
@label(11)
We'll close the show by returning once more to a character
manipulation program.
The program in question,
@i(rstring.c),
takes input one line at a time,
reverses the order of the characters in the input string,
and prints the resulting string.
If,
for instance, you typed in the following line:
@begin(example)
@b(Ye have passed a hell of time . . .)
@end(example)
the program would respond by printing:
@begin(example)
. . . emit fo lleh a dessap evah eY
@end(example)
And if you entered:
@begin(example)
@b(able was i ere i saw elba)
@end(example)
the program would give you:
@begin(example)
able was i ere i saw elba
@end(example)

@i(rstring.c) does its work in three steps:
@begin(enumerate)
it copies a line of input into a character string;

it reverses the order of the characters in the string, and;

it prints the reversed version of the string.
@end(enumerate)
Each of these steps can be handled by a function.
We can use the @i(printf)() function to handle the printing,
and we'll write two functions to do the rest of the work--a
@i(getline)() function to copy each line of input into the string,
and a @i(reverse)() function to change the order of the characters.

@section(The  @i(char) Type, and Character Arrays)
@label(11.1)

Central to our use of these functions is the idea of the @i(char) type
and @i(character string array).  As we mentioned in Section @ref(7), C
will let you declare a variable as having the type @i(char).  Hitherto
we have declared all our character-related variables as @i(ints) so
that we could test for the EOF value.  The only difference between
variables declared as @i(char), and those declared as @i(int) is one
of space.  When you declare a variable as a @i(char), the computer
gives the variable enough space to hold the integer value of a single
character.  The integer @b(127) is the largest value a @i(char)
variable will have to hold (this value corresponds to the @i(del)
character in the ASCII character set).  Variables declared as @i(int)
can hold much larger values.  This difference in space becomes very
important when your program works with character strings.

If you want to have a variable refer to a string of more than one character,
you must declare that variable as an array of @i(chars):
@begin(example)
char line[1000];
@end(example)
This statement declares a character array called @i(line);
the brackets indicate that the variable will hold an array of values,
and the number indicates the maximum number of elements that
array can hold.
When the computer executes the statement,
it sets aside a unit of space for each element,
making each unit large enough to hold a single @i(char) value.

How do you assign values to the elements of the array once you
have declared it?
Use a @i(for) loop.
Suppose,
for instance,
that you wanted to capture ten input characters into an array.
The following lines of code would do the job:
@begin(example)
	char line[10];
	int n;

	for (n = 0; n <= 9; ++ n)
	{
		line[n] = getchar(c);
	}
@end(example)
Notice that we set @i(n) to 0 as opposed to 1,
and we set @i(n's) limit to 9 instead of 10.
In C,
arrays index their elements starting from 0, not 1.
This numbering scheme has tripped up many a programmer,
so beware!

One last thing about character string arrays before we show you the
source code for @i(rstring.c).
When the computer manipulates a character string,
it has to know which character is the string's last character.
Just as you signal the end of input with the EOF constant,
you signal the end of a string with the @b(NUL) character,
'\0'.
You must append a @i(NUL) character to every character array you
put together in a program.
Unlike EOF,
@i(NUL) is not defined in the @i(stdio.h) file.
You must explicitly define it with a @i(#define) statement.

That's enough background information;
here's the program @i(rstring.c).
You should be able to use the program's comments to
figure out what is going on.
@begin(example)
/*
 *	This program reverses characters in input
 *	strings a line at a time, and prints them
 */

#include <stdio.h>
#define NUL '\0'     /* Define the end-of-string NUL character */
#define MAXLEN 1000  /* Define arbitrary limit on length of input line */

main()
{
   	char line[MAXLEN];  /* Character array to hold input line first,
			         then its reversed version */

				/*
				 * While getline() returns input lines--
				 */

	while (getline(line, MAXLEN) > 0)
	{				
	reverse(line);	       /* Reverse each input line */
	printf("%s\n", line);	       /* Print each reversed line */
	}
}

/*
 *	This function copies an input line into
 *	the character array s[]
 */
getline(s, lim)
char s[];
int lim;

{
	int c, n;

			/*
			 * Get input a character at a time
			 * and copy into character array s.
			 * Stop if getchar() returns EOF,
			 * end-of-line, or the limit -1
			 */

   	for(n = 0; (c = getchar()) != EOF && c != '\n' && n < lim - 1; ++n)
   	{
			s[n] = c;   /* Put character into the array */
   	}

   	s[n] = NUL;	    /* Append NUL character to the array */
   	return(n);       /* Return the length of the string in the array */
}
@end(example)
The program continues on the next page.
@begin(example)
/*
 * This function reverses order of characters in character array
 */

reverse(s)
char s[];       /* Declare the character array */
{
	int length, n;
	char r[MAXLEN];		/* The reverse string */

	length = len(s);	/* Get the length of s */

			/*
			 * The following loop reverses characters in s
			 * by copying to r:
			 *
			 * Until we reach the last s character before NUL--
			 */

	for (n = 0; n <= (length - 1); ++n)
	{
		r[n] = s[length - 1 - n];     /* Copy s character to
				         	 appropriate place in r,
				         	 offsetting for the NUL */
	}

			/*
			 * This loop copies reverse string back to s
			 */

	for (n = 0; n <= (length - 1); ++n) {
		s[n] = r[n];
	}
	return;
}

/*
 *	This function determines length of string,
 *	including string's NUL character
 */

len(s)
char s[];
{
	int n;

				/*
				 * The following loop increments n
				 */

	for ( n = 0; s[n] != NUL; ++n)
	{
		;
	}
	return(n);  /* Return string's length */
}
@end(example)

@section(Passing Arrays to Functions)

Earlier we said that when a function passes a variable to
another function,
the function being called gets a copy of the variable,
not the variable itself.
This isn't the case if the variable in question is an array.
When @i(rstring.c)'s @i(main)() function calls @i(getline)(),
@i(getline)() gets direct access to the @i(line) array.
Why?
Because when you use an array name as an argument to a function,
that function gets a @i(pointer) to the array's first element.
The pointer lets @i(getline)() assign characters to the array's elements.
A detailed discussion of pointers and arrays is beyond the scope of
this document;
if you want to know more,
consult a book on C.

You have probably noticed that when we used the @i(line) array
as an argument to @i(getline)(),
we referred to it as @i(line) and not as @i(line)@b([]).
When you want to refer to an array as a whole,
use just the array's name.
Use brackets only when
you want to specify an individual element within the array.

@chapter(Where to Go from Here)

That completes our survey of the @i(essential) elements of the C
language.  As you have probably guessed, we skipped a lot of details.
You have been introduced to only a handful of C's many operators, and
we have not said much of anything about @i(pointers), @i(structures),
@i(unions), and many other elements of the language.  If this document
has whetted your appetite for C, good!  But you need to get a book on
C to really learn the language.  See Appendix @ref(booklist) for a
partial list of C books.

As your programs grow larger and more complicated, you will need to
get acquainted with some of the other programming tools available on
Athena computers.  The Athena document @p[More C] will introduce you
to the most important of these, including:

@Begin(Description)
@i[lint]@\A C program checker that provides error messages more helpful than
	 the C compiler's.

@i[make]@\A utility to help manage the development of programming projects.

@i[rcs]@\A utility that catalogues revisions of source files.

@i[dbx]@\An easy-to-use runtime debugger.

@End(Description)

You should also peruse the articles and @i(man) pages in the Athena
system documentation that discuss C topics.
(Type:  @i(man cc)).
Carefully scan the Athena @p(Programmer's Guide) and @p(Unix Functions Manual),
especially Sections 2, 3, 3F and 3S.
These manuals are available in the cluster documentation racks.

And above all,
good luck in your conquest of C.

@appendix(Appendix:  Shopping for a C Book)
@label(booklist)
The following is a partial list of the many C books
currently flooding the market.
No one has written the perfect C book yet,
but many are quite good.
You will find that each book addresses a slightly different
audience,
and it pays to shop around and find the one that's right for you.

The commentary provided below is purely subjective;
use it only as a guideline.
Take a close look at any book before you take it to the cash register.
The prices range from fifteen to twenty-five dollars,
so choose carefully.

@appendixsection(The Famous Kernighan-Ritchie Book)

@begin(itemize)

@begin(multiple)
@p(The C Programming Language),
by Brian Kernighan and Dennis Ritchie.
Published by Prentice-Hall.
Copyright 1978.

This is the book that everyone's heard of,
and for good reason: @i(Kernighan-Ritchie)
is @i(the) definitive text on C.
But that doesn't mean that it is the book that everyone
should use to learn the language.
@i(K&R) was written for seasoned programmers,
and unless you have a lot of programming experience,
you will probably want to use this book as a reference,
and find another book from which to learn the language.
You will find this book in the documentation racks at
all the clusters.
@end(multiple)

@begin(multiple)
@p(The C Answer Book),
by Clovis L. Tondo and Scott E. Gimpel.
Published by Prentice-Hall, Inc.
Copyright 1985.

This book is a companion to @i(Kernighan-Ritchie);
it provides solutions to all the exercises in
@i(K&R).
If you decide to learn C exclusively from @i(K&R),
you will probably want to get this book.
@end(multiple)
@end(itemize)

@appendixsection(Books for Beginning Programmers)

@begin(itemize)
@begin(multiple)
@p(C Primer Plus),
by Mitchell Waite, Stephen Prata, and Donald Martin.
Published by Howard W. Sams and Company, Inc.
Copyright 1984.

One of the friendliest books on the market.  This book is generous
with examples as well as cartoons.  It covers almost every aspect of
the language, but comes up short when discussing such things as
dynamic allocation of storage.  It comes with a good quick reference
card.  All in all, a very good book for the programming novice.
@end(multiple)

@begin(multiple)
@p(Programming in C with a Bit of UNIX),
by F. Richard Moore.
Published by Prentice-Hall.
Copyright 1985.

This book bills itself as the missing link between the programming
beginner and the C programming language.
It began as a chapter in a book that was written to teach
Music Graduate Students how to use computers to do their work.
It is written for anyone wishing to learn programming.
The book doesn't presuppose that you have had any background in computers,
but it does assume that you are sophisticated in one of several
fields in which computers can be applied:
music, art, literature, science, or engineering.
Although it is written in an appealing style
and covers all aspects of the language,
the book uses examples a little sparingly.
Nevertheless,
it is a good book for people who know nothing about computers.
@end(multiple)

@begin(multiple)
@p(Introduction to C), by Paul M. Chirlian.
Published by Matrix Publishers, Inc.
Copyright 1984.

This book assumes no knowlege of any other computer language.
It covers all aspects of the language,
but tries to present the information so that
the beginner does not get confused.
Well structured,
but not particularly well written.
@end(multiple)
@end(itemize)

@appendixsection(Books for the More Experienced)

@begin(itemize)

@begin(multiple)
@p(A Book on C),
by Al Kelly and Ira Pohl.
Published by The Benjamin/Cummings Publishing Company, Inc.
Copyright 1984.

This book has two very strong points:
it is well organized,
and it has many programming examples.
Anyone who has had some programming experience
will be able to use the book to pick up C,
but the programming beginner will probably have problems
with the presentation and terminology.
@p(A Book on C) covers all aspects of the language,
and can be used as a comprehensive reference.
If you are interested in becoming a serious C programmer,
this might be the book for you.
@end(multiple)

@begin(multiple)
@p(From Pascal to C),
by Douglas L. Brown.
Published by Wadsworth Publishing Company.
Copyright 1985.

As the title suggests,
this book uses Pascal as a springboard to C.
The book presents its examples in both languages
so that Pascal programmers can apply what they already
know while learning C.
Note that the book comes with a pretty good quick reference card.
@end(multiple)

@begin(multiple)
@p(C Programming Guide),
by Jack Purdum.
Published by Que Corporation.
Copyright 1983.

This book assumes that you understand fundamental programming concepts,
but it is written at a level that most people will find comfortable.
In some of the programing examples,
C code is contrasted to BASIC code.
This book includes several useful appendices.
It is one of the least splashy C books on the market . . .
@end(multiple)

@begin(multiple)
@p(The C Puzzle Book),
by Alan R. Feuer.
Published by Prentice-Hall.
Copyright 1982.

This is a good book to test your fluency in C.
It is meant for people who are have sort of learned the language, but
want to consolidate their knowlege.
The book is a series of program puzzles and you get to figure out
what the programs do.
The puzzles will show you just how obscure C code can be.
Each puzzle comes with a detailed solution.
It's a fun book and informative as well.
@end(multiple)
@end(itemize)

@appendixsection(A Book for the Seasoned Programmer)

@begin(itemize)

@begin(multiple)
@p(C--A Reference Manual),
by Samuel P. Harbison and Guy L. Steele, Jr.
of Tartan Laboratories.
Published by Prentice-Hall.

According to the authors, this book grew out of an effort to write a
family of C compilers for several different computers.  As the title
implies, it is a reference book.  The authors are writing for the
serious programmer who wants to and is capable of writing "large and
complex systems in C."  This book comes highly recommended by people
conversant with C.
@end(multiple)
@end(itemize)

@appendix(Appendix:  C Compiler Errors)
@label(errors)
The C Compiler is notorious for its vague,
often misleading, error messages.
Experienced programmers can usually decipher its
cryptic suggestions.
As you go about accumulating experience,
the following notes might help you figure out what is going on.

@appendixsection(Syntax Errors)

The message:
@begin(example)
"bridgecon.c", line 11: syntax error
@end(example)

This is the most frustrating of messages because it doesn't
really tell you anything.
You can't even trust the line number it gives you--sometimes
the error is hiding on the preceding line.
All kinds of things cause this:
missing braces, extra braces, missing semi-colons, missing parentheses . . .
Calls to the @i(printf)() function seem to cause a lot of problems because
you have to get all the details right.
For instance,
the following @i(printf)() call will generate an error message:
@begin(example)
printf("After the fall %d fish were caught\n" pike);
@end(example)
The function call is missing a comma that should separate
the @I(control string) argument from the second argument @i(pike).
Corrected,
the function call looks like this:
@begin(example)
printf("After the fall %d fish were caught\n", pike);
@end(example)

@appendixsection(Undefined Variable Names)

The message:
@begin(example)
"red.c", line 20: @i(variable_name) undefined
@end(example)

You either forgot to declare the variable,
or you haven't spelled it consistently.

@appendixsection(Illegal Characters)

The messages:
@begin(example)
"prst.c", line 7: illegal character: 134 (octal)
"prst.c", line 7: cannot recover from earlier errors: goodbye!
@end(example)

The compiler ran into a character that it didn't recognize.
This error sometimes indicates that you forgot to put single
quotes around a @i(character constant).
For instance,
the following line of code would generate the message:
@begin(example)
while((c = getchar()) != EOF && c != \n)
@end(example)

@appendixsection(Undefined Constants)

The message:
@begin(example)
"ech.c", line 6: EOF undefined
@end(example)

This message should be self-explanatory.
You forgot to tell the preprocessor to include the @i(stdio.h)
header file.
Add the following line to the top of your program,
making sure that you put the # sign in the first column:
@begin(example)
#include <stdio.h>
@end(example)

@appendixsection(Illegal Combinations)

The message:
@begin(example)
"rev.c", line 24: warning: illegal combination of pointer and 
integer, op RETURN
@end(example)

A most devious error message.  It often indicates that you have used an array
incorrectly when calling a function or returning a value from
a function.
Note that you cannot use a function to return an array.

@appendixsection(Undefined Function Names)

The message:
@begin(example)
Undefined:
_@i(functionname)
@end(example)

This message comes from the Link Editor @i(ld).
The Link Editor was unable to find the function's definition.
If the function is a standard function,
you have probably forgot to link to the appropriate library when you
tried to compile.
If the function is user-written,
you have forgotten to include the proper source file when you used @i(cc).
And then there is always the possibility
that you have misspelled the function's name.
