This style guide is a modification of an old C style guide. It should give you clear examples for getting full style/readability credit in 220. The difference from lower level style requirements is that you're expected to be able to program.
The most basic requirement of a program is that it works as intended. By programming with a consistent style, it'll help you code faster and make it easier for others to help or evaluate your code.
The following are general goals of good programming:
Memory usage requirements depend on the assignment. In general, if you want to be sure of full credit, a function should not use O(n) additional memory if it can be implemented with O(1) additional memory.
Beyond optimizing the Big-Oh of a function, the function should run as fast as possible whlie still being readable/extensible. This means that you shouldn't do unnecessary processing, especially inside loops.
| Variables | |
|---|---|
| Good | Bad |
|
distance velocity acceleration |
d ve A b c |
| General functions | |
| Good | Bad |
|
drawPicture squareRoot computePrice |
computeImage (*) sqrt (+) total |
(*) computeImage is worse than drawPicture under the assumption that the function actually draws the image to the screen. The key reason here is that "draw" is more specific than "compute" in this context. In general, you should be as specific as possible while not making the name too long.
(+) sqrt is a complicated case, and depends entirely on the people who are reading your code. If you're writing code for someone that's been programming for a long time (and you yourself have been), it's faster to type sqrt so I'd prefer that. This particular naming convention is similar to user interface design - noone uses 3.5" floppy disks anymore but we're all used to that for a save icon. Because we're all used to knowing what it means, it doesn't matter that the analogy isn't appropriate anymore.
void drawImage(Image i) vs void draw(Image i)void sort(int* array, int size) vs void sortArray(int* array, int size)int* sort(int* data, int size) vs void sort(int* data, int size) , we would assume the second function sorts the array in place while the first function returns a sorted list and doesn't modify the data. We can also communicate to the users of our code through things like the const keyword.
void List::sort() vs void List::sortList()The simple meaning of a function can also be a part of a comment above the function. While such comments are crucial in good code, they are often not seen or known by the programmer writing a function call.
h in shellsort
h is simply a variable in the algorithm specification, so even though it's not descriptive it's fine to use it.
a in r, g, b, a
If you're familiar with graphics code, you know a means alpha.
meters)
YARDS_PER_METER)
computeDistance)
rows_in_file
rowsInFile
int main(void)
{
printf("Hello\n");
printf("Hello again\n");
return 0;
}
int main(void)
{
printf("Hello\n");
printf("Hello again\n");
return 0;
}
There are a few styles of placing curly braces { } in code. I've listed three styles below, but there are probably others; just make sure you stick with one.
int main(void)
{
printf("Hello\n");
printf("Hello again\n");
return 0;
}
int main(void) {
printf("Hello\n");
printf("Hello again\n");
return 0;
}
int main(void)
{
printf("Hello\n");
printf("Hello again\n");
return 0;
}
x = x0 + v0 * t + .5 * a * pow(t, 2);
| Good |
x = x0 + v0*t + .5*a* pow(t, 2);
| Good - can see the precedence grouping easily |
x=x0+v0*t+.5*a*pow(t, 2);
| Bad - tough to read |
/*
Keith Trnka (idont@wantmorespam.com)
CISC220 Lab 2
This program reads some velocities, times, and accelerations from DISTANCE.DAT
and writes out a table of information to DISTANCE.OUT.
*/
int main(void)
{
/* shows "Hello" on the screen */
printf("Hello\n");
/* shows "Hello again" on the screen */
printf("Hello again\n");
/* exits the program normally */
return 0;
}
int main(void)
{
printf("Hello\n"); /* shows "Hello" on the screen */
printf("Hello again\n"); /* shows "Hello again" on the screen */
return 0; /* exits the program normally */
}
/* Initialize balance */
balance = 0;
/* Initialize server address */
memset(&server_address, 0, sizeof(server_address));
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
server_address.sin_port = htons(SERVER_TCP_PORT);
/* Open the listening socket */
if ((sock_server = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("Server: Couldn't open listening socket");
exit(1);
}
...
printFirstRow(initialVelocity, time, acceleration, computeDistance(initialVelocity, time, acceleration))
...
It should be clear what this code does, even though you don't have the code for the functions printFirstRow and computeDistance.
Now look at another way to write it:
...
distance = initialVelocity * time + .5 * acceleration * pow(time, 2);
printf("%10d%10d%10d%10.1lf", initialVelocity, time, acceleration, distance);
...
Coincidentally, this method of programming helps both debugging and extensibility. To see how, we need to look at a larger portion of each program. I've used to comment /* read from file */ as a placeholder for scanf statements.
| Using your own functions | Without your own functions |
|---|---|
...
|
...
|
Now, suppose that I tell you that your columns are incorrect. Maybe each column should be 15 characters wide instead of 10 characters wide. If you use your own functions, all you need to do is fix those functions. If you did the other way, now you must change every line. This demonstrates how functions can lead to extensible programs. But it's also important for debugging: without functions, you might forget to fix one row or make one typo, but with functions as shown above, you can't make those mistakes.
Here's some code with a long line:
double meters1, meters2, meters3, meters4, kilometers1, kilometers2, kilometers3, kilometers4, yards1, yards2, yards3, yards4;
You can group things together so that they fit within the page:
double meters1, meters2, meters3, meters4,
kilometers1, kilometers2, kilometers3, kilometers4,
yards1, yards2, yards3, yards4;
Sometimes you might do this with a printf too:
printf("My %d buttons were exploring the Amazon when they discovered that they couldn't eat %d chickens.",
buttons, chickens);
You can also comment too much. If you find that you place a comment along with every line of code, you're probably commenting too much. Think about it like this: if you showed your code to someone in the class who doesn't really know you, you should only have comments on the things that they'll have trouble figuring out.
acceleration = 10. Have your program output the results using printf. As a second step, output to a file instead of to the screen. As a third step, read values from a file instead of hard-coding them.
Another way to approach this is to write functions that do the different parts of your program. Test each function separately before putting it all together.
The example I gave on the first day of class is something that helps with debugging: if you're used to writing things like if (0 == i) rather than if (i == 0) you won't be as confused if you don't press the '=' key hard enough one time.