CSSE2310/CSSE7231 C Programming Style Guide Version 2.0.4 The University of Queensland School of Information Technology and Electrical Engineering September 2017 Programs written for CSSE2310/7231 assignments must follow the style guidelines outlined in this document. Where the style guide is open to interpretation, the choices you make regarding your personal style must be consistent throughout your project. 1 Naming Conventions 1.1 Variable and File names Variable names and file names will begin with a lowercase letter and names with multiple words will use initial capitals for subsequent words. Names that are chosen should be meaningful and Hungarian notation is NOT to be used. Source files must be named with the suffix .c or .h (lower case). Example variable names: book, newCount, setWordLength Example filenames: hello.c, stringRoutines.c, shared.h Unacceptable variable names: FILE *fp; char *aPtr; char *thingStr; 1.2 Defined constants and macros Preprocessor constants and macros, ie. those defined using #define, must be named using all uppercase letters, with underscores ( ) used to seperate multiple words. NOTE: Variables declared with the const keyword are to use variable naming, as per 1.1. Examples: MAX BIT, DEFAULT SPEED 1.3 Function names Function names should all be lowercase and use underscores to separate multiple words. Example function names: main(), reset secret string() 1.4 Type names Type names (i.e. from typedefs), structure and union names should begin with capital letters and use initial capitals for subsequent words. Example typedef/structure/union names: Contact, FileData, struct Node /∗ A player with in the game ∗/ s t r u c t Player { char ∗name ; i n t s co r e ; s t r u c t Player ∗next ; } ; Example 1: Struct naming and declaration /∗ Point ( coo rd inate ) ∗/ typede f s t r u c t { i n t x ; i n t y ; } Point ; Example 2: Typedef struct naming and declaration 1 1.5 Enumerated Types Enumerated types must be named in the same way as any other type (see 1.4). Members of an enumerated type must follow the same naming as constants (see 1.2). /∗ Card s u i t s ∗/ enum CardSuits { CLUBS, DIAMONDS, HEARTS, SPADES } ; Example 3: Enumerated type naming and horizontal layout /∗ Program ex i t codes ∗/ enum ExitCodes { EXIT SUCCESS = 0 , EXIT ARGS = 1 , EXIT FAILURE = 2 } ; Example 4: Enumerated type naming and vertical layout, with explicit value selection 2 Comments Comments should be generously added to describe the intent of the code. They are expected in code which is tricky, lengthy or where functionality is not immediately obvious. It is reasonable to assume that the reader has a decent knowledge of the C programming language, so it is not necessary to comment every line within a function. Comments must be present and meaningful for each of the following: • Global variables • Function declarations or definitions • Enum definitions • Struct definitions Function comments should describe parameters, return values and error conditions. They should not include parameter types, nor should they include the function prototype. If an adequate comment is given for a function declaration, it need not be repeated for the associated function definition. No comment is needed for the main() function. 2 3 Braces Use braces { } around statements in the body of if, else, for, while, do, etc statements. The C language does not require braces when the body contains only one statement, but you must surround it with braces anyway. This helps avoid errors while changing your code. An open brace appears at the end of the line after an if statement/loop statement/etc (with at least one space before the brace). The closing brace should be lined up underneath the start of the function/loop statement/etc. Braces for structure declarations and array initialisations do not need to follow this layout. The opening brace for a function definition may be either at the end of the line following the arguments or in the left most column of the next line. /∗∗ ∗ Ca l cu l a t e s the i n t e g e r sum of i n t e g e r s 1 through n . ∗ Returns t h i s sum , or 0 i f n i s 0 or l e s s . ∗ (Note : won ’ t work i f n i s l a r g e enough to cause the sum to over f l ow ) ∗/ i n t sum( i n t n) { /∗ This brace can be at the s t a r t o f the next l i n e ∗/ i n t i , s = 0 ; f o r ( i = 1 ; i <= n ; i++) { /∗ This brace must be here ∗/ s += i ; } r e turn s ; } Example 5: Correct braces for a function f o r ( . . . ; . . . ; . . . ) { . . . } Example 6: Correct braces: for loop whi le ( . . . ) { . . . } Example 7: Correct braces: while loop do { . . . } whi le ( . . . ) ; Example 8: Correct braces: do while loop i f ( . . . ) { . . . } Example 9: Correct braces: if statement i f ( . . . ) { . . . } e l s e i f ( . . . ) { . . . } e l s e { . . . } Example 10: Correct braces: if-else switch ( . . . ) { case . . . : . . . break ; d e f au l t : . . . } Example 11: Correct braces: switch statement 3 4 Whitespace Meaningful parts of code are grouped together by using the whitespace as a separator. Whitespace is composed of horizontal whitespace (i.e. space and tab characters) and vertical whitespace (i.e. blank lines). 4.1 Vertical whitespace Organize your source code into meaningful parts. For example, use blank lines to separate functions from each other. Blank lines are also used to separate groups of statements from each other to make the major steps of an algorithm distinguishable. /∗ Mult ip ly two numbers ∗/ i n t mult ip ly ( i n t x , i n t y ) { r e turn x ∗ y ; } /∗ Divide two numbers ∗/ i n t d i v id e ( i n t x , i n t y ) { r e turn x / y ; } Example 12: Acceptable vertical whitespace between functions 4.2 Horizontal whitespace Use horizontal whitespace to organize each line of code into meaningful parts. It is bad style to not use spaces within a line. Space must be added after each comma, as well as each semicolon that is not on the end of a line. Space should also be added either side of all assignment and binary operators (= += / - * + etc). There should be no spaces added around unary operators (& * + - ~ ! ++ --) and struct operators (point->x, player.name). Acceptable horizontal whitespace add up(a , b , c , d ) ; i n t ∗a , b , c [ 1 0 ] ; Example 13: Acceptable horizontal whitespace: commas f o r ( i = 0 ; i < 10 ; i++) Example 14: Acceptable horizontal whitespace: semi- colons a = (b + c ) ∗ d ; Example 15: Acceptable horizontal whitespace: assignment and binary operators i n t x = −y ; b = ∗c ; width = point−>y ; Example 16: Acceptable horizontal whitespace: unary and struct operators Unacceptable horizontal whitespace add up(a , b , c , d ) ; i n t ∗ a , b , c [ 1 0 ] ; Example 17: Unacceptable horizontal whitespace: commas f o r ( i =0; i <10; i++) Example 18: Unacceptable horizontal whitespace: semi-colons a=(b+c ) ∗d ; Example 19: Unacceptable horizontal whitespace: assignment and binary operators i n t x = − y ; b = ∗ c ; width = point −> y ; Example 20: Unacceptable horizontal whitespace: unary and struct operators 4 5 Indentation Use indentation to indicate the level of nesting. Indentation must occur in multiples of four spaces. You should configure your editor so that indents are in multiples of four spaces (but tab stops must remain at 8 characters). You should indent once each time a statement is nested inside the body of another statement. Always indent whether or not the control structure uses braces. i f ( day == 31) { monthTotal = 0 ; f o r (week = 0 ; week < 4 ; ++week ) { monthTotal += r e c e i p t s [ week ] ; } } Example 21: Correct indentation: if statement i f (month >= 1 && month <= 3) { quarte r = 1 ; } e l s e i f (month >= 4 && month <= 6) { quarte r = 2 ; } e l s e i f (month >= 7 && month <= 9) { quarte r = 3 ; } e l s e { quarte r = 4 ; } Example 22: Correct indentation: chained if-else switch (month) { case 2 : daysInMonth = 28 ; break ; case 4 : case 6 : case 9 : case 11 : daysInMonth = 30 ; break ; d e f au l t : daysInMonth = 31 ; break ; } Example 23: Correct indentation: switch statement If you use the gnu indent tool consider the following options as a starting point: -linux -i4 -cli4 -l79 --no-tabs 5 6 Line Length Lines must not exceed 79 columns in length including whitespace. The “standard” screen size is 80 columns. Occasionally an expression will not fit in the available space in a line; for example, a function call with many arguments, or a logical expression with many conditions. Such occurrences are especially likely when blocks are nested deeply or long identifiers are used. If a long line needs to be broken up, you need to take care that the continuation is clearly shown. For example, the expression could be broken after a comma in a function call (ideally never in the middle of a parameter expression), or after the last operator that fits on the line. The following continuation must be double indented (8 spaces) so that it is clearly identifiable. If more than one continuation line is required, no further indenting is required. someFunction ( longExpress ion1 , longExpress ion2 , . . . . . , longExpress ionN ) ; i f ( express ionA | | express ionB | | express ionC | | express ionD | | express ionE | | express ionF ) { /∗ code goes here − indented by 4 spaces ∗/ . . . } i f ( express ionA | | express ionB | | express ionC | | express ionD | | express ionE | | express ionF | | express ionG | | express ionH | | e xp r e s s i on I ) { /∗ code goes here − indented by 4 spaces ∗/ . . . } Example 24: Correct line length and indentation 7 Overall Source code should be written to be clear and readable. Anything which works against your code being clear and readable may incur additional “general” penalties. For example (but not restricted to): • Use of global variables should be limited to an absolute minimum, where functionality of the program deems them necessary. • Defined constants should be used instead of number and character literals (ie. magic numbers) scattered throughout code without context. 7.1 Compilation Your assignments will use the C99 standard, and must be compiled with the following flags as a minimum: -Wall -pedantic -std=gnu99 No warnings or errors should be reported. If warnings or errors are reported, they will be treated as style violations. Every source file in your assignment submission (including .c files and any custom .h files they #include) will be checked for style exactly as committed to the repository. This applies whether or not they are linked into executables. To facilitate this process, any .c files in your submission which do not compile individually (ie gcc -c file.c +relevant flags) will attract an additional penalty equivalent to 5 compiler warnings per file. Every .h file in your submission must make sense without reference to any other files, other than those which it references by #include. Specifically, any declarations must be complete and all types, declarations and any definitions used in the .h file must either come from the .h file itself, or from included headers. Any components which are obfuscated, not in standard forms or need to be transformed by extra tools in order to be readable will be deemed to be without academic merit and will be removed before compilation is attempted. 7.2 File encoding All source files must use an ASCII-compatible encoding. Files should use Unix line endings (\n). 6 7.3 Function length Functions should not exceed 50 lines in length, including any comments. If a function is longer than 50 lines, then it is a good candidate for being broken into meaningful smaller functions. In exceptional circumstances (which should be documented with a comment), functions may be longer than 50 lines. 7.4 Modularity Principles of modularity should be observed. Related functions and variable definitions should be separated out into their own source files (with appropriate header files for inclusion in other modules as necessary). You should also use functions to prevent excessive duplication of code. If you find yourself writing the same or very similar code in multiple places, you should create a separate function to undertake the task. 8 Banned Language Features Use of any of the following C features in your assessments is grounds for a mark of zero in that assessment. All of them work against readable and well structured programs. None of these are things you could do by accident. • Goto: While goto is a legal part of the C language, nothing in this course requires its use. • Digraphs and Trigraphs: This course uses systems which support ASCII or unicode and so have all the required characters. 7
欢迎咨询51作业君