CSCI-E26 C Style Sheet

Introduction
C is a powerful, flexible language. Used properly, C makes programming easier and more efficient. Used sloppily, it makes programming a nightmare. Two principles guide C and Unix programming: `keep it simple' and `use it over and over.' Each C program should be constructed from a collection of clear, modular functions. Each function should perform a specific task. Each function should be self-contained so that it can be snapped into another program years later by someone else. As you program in C, you should develop a collection of programs composed of functions that you can reuse. After several years, you should find you can write new programs by rummaging though your old code and reusing stuff you wrote years ago. This is not an ideal; ask seasoned C programmers if they reuse old code. Ask them if they borrow functions from other people.

Rules to Code By
Given that you will want to reuse your code and that other people will want to borrow your functions, how do you write C ? Three words should guide you:

Start now, that way you won't have to unlearn bad habits.

1. Modularity
Modularity means the program consists of clearly defined functions working together to perform the operation. Functions communicate by passing arguments and returning values. Each function accepts a list of parameters and returns a value. If it is a filter, then it performs some action on the standard data stream and may or may not return a value. It uses no global variables. Global variables undermine the reusability of a function. All its working storage should be local variables. Global variables can be risky. See an example of the dangers of global variables

Modularity means each part of the program is simple, not complicated. Each function does one thing well. If there are two things to do, write two functions. There are two main reasons for this rule. The first reason is that simple functions are easier; easier to write, easier to understand, and easier to debug. Once you define the single purpose of a function, you can code it, check it, and be done with it. A complicated function has many more ways to go wrong.

The second reason is that simple functions are more useful. You may later want to reuse a function that finds the date of Thanksgiving for a given year. It would be a nuisance if that same function also baked a pumpkin pie.

main() Must be Short: Do not put much code in main(). The main() function should be the top-level abstraction for your program. It should call a few functions that show the main structure of your program. Those functions should do the work or call their own helper functions to do the work. To repeat: do not put much code in main().

2. Readability
Readability means two things: how well code is arranged on the screen and how well objects are named. Arrange your code to reflect the logical structure of the solution. For example, if a function consists of an initialization, a main loop, and a wrap-up, there should be three visually distinct sections to the function. Functions, variables, and symbolic constants (#define stuff) should have names that describe their role. Avoid using variables like a, b, and c. Instead, use variables like fahr_temp or input_line. Use all upper case letters for symbolic constants and lower case or mixed case for variables and functions.

30-Line Rule: Your functions should be short: 30 lines at most. If a function exceeds 30 lines, it is doing too much. Break it into smaller functions.

80-Column Rule: Your code should fit on a compact window: 80 columns at most. We grade your assignment with one terminal window and one browser window side by side. We want your code to fit in a terminal window 80 columns wide.

Indentation Rules: Indent all functions, all loops, conditional blocks, and cases. It is acceptable to indent with tabs. Indenting by eight spaces makes the structure very clear, but four is acceptable. Two is not acceptable.

3. Documentation
Ever write some code late at night and come back to it the next day unable to figure out what you were doing? Ever been given someone else's code to enhance and been unable to figure out what the variables stand for or what the functions do? Ever start a piece of code and get lost half-way into it?

Good documentation should permeate your code. In particular:

File headers Each file must have a header that describes the purpose of that set of functions, lists the public functions in the file, and offers any hints or warnings about using the set of functions in the file.
Function headers Each function must have a header comment that describes the purpose of the function, the meaning of each of its arguments, the meaning of the return value, the possible error conditions, and a brief outline of the method the function uses to do its work. You do not need to be wordy here; clear, simple statements do the trick.

For example:

	/*  is_logname_valid(const char *s)
	 *  purpose: determine if string represents
	 *            a valid logname on system
	 *     args: string
	 *     rets: 1 if true, 0 if not
	 *     note: this function ignores case
	 */
	int is_logname_valid( const char *s )
Local Variables The local variables must have names that describe their purpose. Each variable should also get a descriptive comment.
Code Paragraphs Each chunk of code in the function needs a brief description to explain where it fits in the flow of the function. Its role may make perfect sense to you at 4:30 am, but might not seem so clear to you a week later. Furthermore, explaining a piece of code helps clarify your logic. It is nicer to catch logic errors at the time you write the code than after several days of debugging illogical code.
Sneaky Lines C invites you to write clever, efficient code. As you get used to the language, you will find yourself writing code that looks a little weird. When you feel that twinge of cleverness, put a comment like:
/* yes, I mean =, it should not be == */

Grading on Function and Design
You programming assignments will be graded on function and design. Part of the value of a C program is that it works for its original purpose. The rest of the value of a C program is that its functions can be used later, in other ways, by other people. Write for the present and for the future. Program function counts for 70 percent, and Modularity, Readability, and Documentation count for about 10 percent each.


Last update 20 Sep 2023, 14:53