06 Beginner's Lesson 2: Style

Greetings,

First, it has been mentioned to me that I should point out something
NOT to do when compiling our source code.
This is the correct command:
$ gcc -o hello hello.c
Doing it this way is not a good idea (try it and see why).
$ gcc -o hello.c hello

In Lesson One we got started by making sure the GNU C compiler was
installed, and also wrote our first C program. In this lesson we'll
go over that first program, line by line, and discuss it. It seems
that the hello.c program in Lesson One had an error: no comments.

In C, comments are put inside of a pair of slash-asterisk, asterisk-
slash, like this: /* comment goes here */ Comments are not read
by the compiler. Comments are meant to be read by human beings.
Comments are documentation. I've often heard experienced program-
mers say that comments are unneccessary with well-written code,
but we are not yet that experienced, so getting into the habit of
commenting our source code is a good one to get into to.
At the very least, our program should identify the program name,
the date written, the author, and the purpose of the program.

Here is hello.c with comments:

/* Name: hello.c */
/* Purpose: First C program */
/* Author: kwmelvin */
/* Date: 8 Oct 2002 */
#include <stdio.h>

int main(void)
{
printf("hello, world\n");

return 0;
}

Comments can extend over more than one line; once it has seen the
/* symbol, the compiler will ignore everything until it encounters
the */ symbol. So the above comment can also be written as:

/* Name: hello.c
Purpose: First C program
Author: kwmelvin
Date: 8 Oct 2002 */

Sometimes a comment like that can be difficult to read, so putting
the end */ symbol on a line by itself makes it clear:

/* Name: hello.c
Purpose: First C program
Author: kwmelvin
Date: 8 Oct 2002
*/

Even better, put a "box" around the comment:

/*******************************
* Name: hello.c *
* Purpose: First C program *
* Author: kwmelvin *
* Date: 8 Oct 2002 *
*******************************/

Here is a nifty thing to add to your .exrc file to help make a
box around your comments:

:abbr #b /*************************************************************
:abbr #e *************************************************************/

Now when you are using vi, and want to add a box, simply type "#b" and
press <enter> and you'll get a string of asterisks preceeded by a slash.
Typing "#e" and pressing <enter> will put a string of asterisks with a
slash at the end. Cool. ;-)

Comments can also go on the same line as program code:

printf("\n"); /* output a newline */

Don't forget to terminate your comments! In vim, with color syntax
highlighting turned on, the comments are bright cyan on my computer.
(I just wish I knew how to turn on numbered lines in vim, then I'd
have the best of both worlds--I couldn't find it on the manpage.)

Not all programs need all of these things, but here are some things
that can make a program better documented:

Heading: The first comment should contain at least the name of the
program, and a short description of what it does.

Author: Take credit for your work. Also, other people know who to
contact to report bugs, or better yet, who to give praise to!

Purpose: What does this program do? Why did you write it?

Usage: At least give the compiler options used to compile the program,
and how to run it.

References: If you've borrowed from other programmers code, give credit
where credit is due.

File formats: List the files that your program reads or writes to, and
what their file format is (text, binary).

Restrictions: List any limits or restrictions that aplpy to the program.

Revision history: Who modified the program, and when and what changes
were made.

Error handling: What the program does when it encounters an error.

Notes: Special comments or info that hasn't already been covered by the
above.

Besides comments, there are other style considerations to become
familiar with. Whitespace and indentation of source code are two ways
of making C source code easier to read by human beings. Here, for
example, is our hello.c program again:

/*hello.c*/#include <stdio.h>
int main(void){printf("hello, world\n");return 0;}

Since C is a freeform language, the above will compile and execute the
same as the example with whitespace and indentation, however any human
being that would have to maintain a program without whitespace or
indentation would grow old before their time! Just compare this to
the hello.c program above that has whitespace and indentation.

When we added the line: set tabstop=2 in our .exim file, we told vi
to move the cursor over 2 spaces when we hit the "Tab" key. To change
that, simply edit the .exrc file and replace the 2 with a 4 or an 8,
or whatever makes the program easy to read for you. I understand that
some companies have a format standard that you must adhere to.
By all means, do it the way they want you to do it. Since I am a
hobbyist, I rather like my tabstops to be 2 spaces.

It seems to be a good practice to indent all looping structures, for
example:

while (1)
{
statement;
statement;
}

Some programmers also do it like this, putting the first brace after
the keyword:

while (1) {
statement;
statement;
}

I think the first example is much easier to read, but the second
example just looks cooler... what do you think? If it is a choice
between looking cool, and being easier to read, I choose clarity.

Here is a nifty trick to use in vi. If you put your cursor on one of
the curly braces, and press the percent "%" key, the cursor will
jump to its partner brace. This also works with parentheses and
brackets. This can be helpful when trying to find out if you've
ended a curley brace, parentheses, or bracket.

Okay, the final thing to say here is to always remember an old rule
of engineering design: Keep it simple. Make your program as simple
and as easy to understand as you can.

I just try to get the program working first. After it is working,
I can go back and clean things up a wee bit. In one of my first
Simpletron programs, my coreDump() function had nine or ten "for"
statements, one for each line of the memory dump. Later, after I got
things working okay, I was able to come back and clean it up with a
couple of nested "for" statements. However, at first, the nine or
ten "for" statements were much easier for me to understand.

Okay, now let's take that hello.c program apart, line by line.
We've already discussed comments, and we know that the C compiler
ignores everything between /* and */. Comments are documentation
that help humans read the program, the machine doesn't need them.

The line after the comments is: #include <stdio.h> This is a C
preprocessor directive. The C preprocessor is like a text
editor of sorts. <stdio.h> is a C Standard Library header file
that deals with Input/Output. In this case, the C preprocessor
replaces this line with the contents of the <stdio.h> file.

The next line is: int main(void) This is the main function of
the program. C is a language that uses functions, some predefined
and others defined by the programmer. Every C program must have
a main() function. Here, the "int" is the value returned by the
main() function (see return 0; later on). The void in the
parentheses means that there are no arguments to the main() function.
The simplest program that will compile with GNU C is: main(){}
It really isn't much of a program because it doesn't DO anything,
but it will compile and run. The resulting executable is 4604 bytes
in size, from a source code file that is 9 bytes in size (8 characters
plus a newline).

The main() function has its statements inside curley braces. It is the
statements within the braces that make a program do something. Don't
forget that parentheses, braces, and brackets always come in pairs,
so remember to add the end brace, etc., in your program.

The first statement in the main() function is a call to the predefined
printf() function. printf() is defined in the Standard C Library file
stdio.h. printf() in this case takes a string as an argument. The
string is enclosed in double quotes. The "\n" symbol is a newline.
Try taking the newline out of the program, compile it, and see what
happens. Note that all statements in C are ended with a semi-colon.
Leaving the semi-colon off a statement is a typical beginner's error.
Try taking the semi-colon off the end of the statements, compile the
source code, and see what the compiler errors say.

The next statement is: return 0; In this case, return returns a zero
to main(). This tells the operating system that the program exited
normally (Status=0). A non-zero status usually means an error.

Last, but not least, the end curly brace tells the compiler that the
program is done. That's it for now. Any questions? All mistakes in
this lesson are mine.

Happy Programming!
--
K