/** *********************** * C Programming Style for Engineering Computation * Created by Aidan Nagorcka-Smith (aidann@student.unimelb.edu.au) 13/03/2011 * Definitions and includes * Definitions are in UPPER_CASE * Includes go before definitions * Space between includes, definitions and the main function. * Use definitions for any constants in your program, do not just write them * in. * * Tabs may be set to 4-spaces or 8-spaces, depending on your editor. The code * Below is ``gnu'' style. If your editor has ``bsd'' it will follow the 8-space * style. Both are very standard. */ /** * GOOD: */ #include #include #define MAX_STRING_SIZE 1000 #define DEBUG 0 int main(int argc, char **argv) { ... /** * BAD: */ /* Definitions and includes are mixed up */ #include #define MAX_STING_SIZE 1000 /* Definitions are given names like variables */ #define debug 0 #include /* No spacing between includes, definitions and main function*/ int main(int argc, char **argv) { ... /** ***************************** * Variables * Give them useful lower_case names or camelCase. Either is fine, * as long as you are consistent and apply always the same style. * Initialise them to something that makes sense. */ /** * GOOD: lower_case */ int main(int argc, char **argv) { int i = 0; int num_fifties = 0; int num_twenties = 0; int num_tens = 0; ... /** * GOOD: camelCase */ int main(int argc, char **argv) { int i = 0; int numFifties = 0; int numTwenties = 0; int numTens = 0; ... /** * BAD: */ int main(int argc, char **argv) { /* Variable not initialised - causes a bug because we didn't remember to * set it before the loop */ int i; /* Variable in all caps - we'll get confused between this and constants */ int NUM_FIFTIES = 0; /* Overly abbreviated variable names make things hard. */ int nt = 0 while (i < 10) { ... i++; } ... /** ******************** * Spacing: * Space intelligently, vertically to group blocks of code that are doing a * specific operation, or to separate variable declarations from other code. * One tab of indentation within either a function or a loop. * Spaces after commas. * Space between ) and {. * No space between the ** and the argv in the definition of the main * function. * When declaring a pointer variable or argument, you may place the asterisk * adjacent to either the type or to the variable name. * Lines at most 80 characters long. * Closing brace goes on its own line */ /** * GOOD: */ int main(int argc, char **argv) { int i = 0; for(i = 100; i >= 0; i--) { if (i > 0) { printf("%d bottles of beer, take one down and pass it around," " %d bottles of beer.\n", i, i - 1); } else { printf("%d bottles of beer, take one down and pass it around." " We're empty.\n", i); } } return 0; } /** * BAD: */ /* No space after commas * Space between the ** and argv in the main function definition * No space between the ) and { at the start of a function */ int main(int argc,char ** argv){ int i = 0; /* No space between variable declarations and the rest of the function. * No spaces around the boolean operators */ for(i=100;i>=0;i--) { /* No indentation */ if (i > 0) { /* Line too long */ printf("%d bottles of beer, take one down and pass it around, %d bottles of beer.\n", i, i - 1); } else { /* Spacing for no good reason. */ printf("%d bottles of beer, take one down and pass it around." " We're empty.\n", i); } } /* Closing brace not on its own line */ return 0;} /** **************** * Braces: * Opening braces go on the same line as the loop or function name * Closing braces go on their own line * Closing braces go at the same indentation level as the thing they are * closing */ /** * GOOD: */ int main(int argc, char **argv) { ... for(...) { ... } return 0; } /** * BAD: */ int main(int argc, char **argv) { ... /* Opening brace on a different line to the for loop open */ for(...) { ... /* Closing brace at a different indentation to the thing it's closing */ } /* Closing brace not on its own line. */ return 0;} /** ************** * Commenting: * Each program should have a comment explaining what it does and who created * it. * Also comment how to run the program, including optional command line * parameters. * Any interesting code should have a comment to explain itself. * We should not comment obvious things - write code that documents itself */ /** * GOOD: */ /* change.c * * Created by Aidan Nagorcka-Smith (aidann@student.unimelb.edu.au) 13/03/2011 * * Print the number of each coin that would be needed to make up some change * that is input by the user * * To run the program type: * ./coins --num_coins 5 --shape_coins trapezoid --output blabla.txt * * To see all the input parameters, type: * ./coins --help * Options:: * --help Show help message * --num_coins arg Input number of coins * --shape_coins arg Input coins shape * --bound arg (=1) Max bound on xxx, default value 1 * --output arg Output solution file * */ int main(int argc, char **argv) { int input_change = 0; printf("Please input the value of the change (0-99 cents inclusive):\n"); scanf("%d", &input_change); printf("\n"); // Valid change values are 0-99 inclusive. if(input_change < 0 || input_change > 99) { printf("Input not in the range 0-99.\n") } ... /** * BAD: */ /* No explanation of what the program is doing */ int main(int argc, char **argv) { /* Commenting obvious things */ /* Create a int variable called input_change to store the input from the * user. */ int input_change; ... /** **************** * Code structure: * Fail fast - input checks should happen first, then do the computation. * Structure the code so that all error handling happens in an easy to read * location */ /** * GOOD: */ if (input_is_bad) { printf("Error: Input was not valid. Exiting.\n"); exit(EXIT_FAILURE); } /* Do computations here */ ... /** * BAD: */ if (input_is_good) { /* lots of computation here, pushing the else part off the screen. */ ... } else { fprintf(stderr, "Error: Input was not valid. Exiting.\n"); exit(EXIT_FAILURE); }