16.070: Introduction
to Computers and Programming
Above all, remember: clever code is unreadable code.
Save your cleverness for algorithms and document them well.
Ø
YOU MUST follow this rule
Key:
·
We recommend you follow this rule
IF
Ø IFs with ELSE IF clauses
should always include an ELSE block even if it’s only an error message.
INCORRECTif (a>5) {
printf(“a is large\n”); } /* end if large case */ else if ( (a<=5) && (a>3) ) {
printf(“a is small\n”); } /* end else if small case */ |
CORRECTif (a>5) {
printf(“a is large\n”); } /* end if large case */ else if ( (a<=5) && (a>3) ) {
printf(“a is small\n”); } /* end else if small case */ else {
printf(“error!\n”); } /* end else error case */ |
INCORRECTif (x>10) if (y>6) z
= a + b; |
CORRECTif ((x>10) && (y>6)) { z
= a + b; } /* end if to check x and y */ |
Ø IFs with ELSE IF clauses
should form an exhaustive set of alternatives
INCORRECTif (a>5) {
printf(“PosNum is large\n”); } /* end if large case */ else if ( (a<=5) && (a>3) ) {
printf(“a is small\n”); } /* end else if small case */ else {
printf(“error!\n”); } /* end else error case */ |
CORRECTif (a>5) {
printf(“a is large\n”); } /* end if large case */ else if ( (a<=5) && (a>3) ) {
printf(“a is medium\n”); } /* end else if small case */ else if (a<=3) {
printf(“a is small\n”); } /* end else if small case */ else {
printf(“error!\n”); } /* end else error case */ |
Unnecessary if (a==0) {
printf(“invalid entry for x\n”); } /* end x is 0 */ else {
printf(“x is ok\n”); } /* end else x is not 0*/ |
CORRECTif (a==0) {
printf(“invalid entry for x\n”); } /* end x is 0 */ |
INCORRECTif (a>5) {
if (b>5) {
printf(“ok\n”);
} /* end if b>5 */
else {
printf(“not ok\n”);
} /* end else not ok */ } /* end if a>5 */ |
CORRECTif ( (a>5) && (b>5) ) {
printf(“ok\n”); } /* end x is ok */ else if ( (a>5) && (b<=5) ) {
printf(“not ok\n”); } /* end else if x is not ok */ else if (a<=5) {
/* do nothing */ } /* end if a<=5 */ else {
printf(“error\n”); } /* end else error case */ |
INCORRECTif (x==0) { printf(“invalid
x value\n”); } else { z
= q/x; } |
CORRECTif (x==0) { printf(“invalid
x value\n”); } /* x is not valid */ else { z
= q/x; } /* x was not 0 */ |
INCORRECTif (x>10) z
= a + b; else if (y>6) z
= a + b; |
CORRECTif ( (x>10) || (y>6) ) { z
= a + b; } /* end if x and y are in range */ |
INCORRECTif (x>10) z
= a + b; |
CORRECTif ( (x>10) || (y>6) ) { z
= a + b; } /* end if x and y are in range */ |
BOOLEAN EXPRESSIONS
INCORRECTx = 0; y = 3; if ((x != 0) && (y/x > 2) z
= x + y; /* if (y/x > 2) is evaluated * before the && a runtime * divide by zero error will * occur since x is zero
*/ |
CORRECTx = 0; y = 3; if (x != 0) { if (y/x > 2) { z
= x + y;
} /* end if yx ratio is valid */ } /* end if x is not 0 */ /* Nesting protects y/x from
evaluation in case x is zero */ |
Ø Conditional expressions
should not have side effects.
INCORRECTif (++j > 6) {
printf(“j > 6\n”); } /* end if */ |
CORRECTj++; if (j > 6) {
printf(“j > 6\n”); } /* end if */ |
INCORRECT(x>10 && y>6 &&
q<4) |
CORRECT( ((x>10) && (y>6))
&& (q<4) ) |
ARRAYS
Ø Use constants to define
your array bounds. It makes writing
loop code more scalable.
INCORRECTint Array[5]; |
CORRECT#define SIZE 5 int Array[SIZE]; |
FOR
Ø When traversing arrays,
use attributes of the array definition to define the bounds of iteration.
INCORRECT#define SIZE 5 int Array[SIZE]; for (x=0; x<5; x++) {
Array[x] = 0; } /* end for to loop */ |
CORRECT#define SIZE 5 int Array[SIZE]; for (x=0; x<SIZE; x++) {
Array[x] = 0; } /* end for to loop */ |
INCORRECT/* this is a function that
never ends */ int func(void) { const int ever = 1; for (ever;;) { printf("looping\n"); }
/* end infinite for */ return 0; } /* end func() */ |
CORRECT/* this is a function that
never ends */ int func(void) { const int ALWAYS = 1; while (ALWAYS){ printf("looping\n"); }
/* end infinite while */ return 0; } /* end func() */ |
WHILE
INCORRECT/* function exits when x==5 */ int func(void) {
int x = 0; while (1){
x++;
if (x==5) {
return x;
} /* end if x==5 */ }
/* end while to iterate x */ } /* end func() */ |
CORRECT/* function exits when x==5 */ int func(void) {
int x = 0;
int Proceed = 1; while (Proceed){
x++;
if (x==5) {
Proceed = 0;
} /* end if x==5 */ }
/* end while to iterate x */ return x; } /* end func() */ |
INCORRECT/* this is a while that
exits when x is 5 */ x=0; Stop=0; while (!Stop){
x++;
if (x==5) {
Stop = 1;
} /* end if x==5 */ } /* end while to iterate x */ |
CORRECT/* this is a while that
exits when x is 5 */ x=0; Continue=1; while (Continue){
x++;
if (x==5) {
Continue = 0;
} /* end if x==5 */ } /* end while to iterate x */ |
SWITCH / CASE
Ø Include a default
condition even if you think it will never be reached during normal operation.
INCORRECTswitch (a) {
case 1: /* first case
*/
printf(“first case\n”);
break;
case 2: /* second case
*/
printf(“second case\n”);
break; } /* end switch to test a */ |
CORRECTswitch (a) {
case 1: /* first case
*/
printf(“first case\n”);
break;
case 2: /* second case
*/
printf(“second case\n”);
break;
default: /* error case */
printf(“error case\n”);
break; } /* end switch to test a */ |
General Guidelines
NAMING
INCORRECTint x = 0; |
CORRECTint PositionIndex = 0; |
Ø Name constants using all
capitals and variables using mostly lowercase.
INCORRECTconst int upper_bound = 5; int counter = 0; |
CORRECTconst int UPPER_BOUND = 5; int Counter = 0; |
INCORRECTint TotalCount; int main(void) { … } /* end main */ |
CORRECTint gTotalCount; int main(void) { … } /* end main */ |
Ø Pointer variable names
should begin with p or with p_ .
INCORRECTint * QueueHead; |
CORRECTint * p_QueueHead; |
INCORRECTint NmCorAns = 0; |
CORRECTint NumCorrectAns = 0; /* variable contains the number
of correct answers */ |
INCORRECTint x = 0; /* number of boats */ int y = 0; /* number of cars
*/ int z = 0; /* number of vehicles */ z = x+y; |
CORRECTint NumBoats = 0; int NumCars = 0; int NumVehicles = 0; NumVehicles = NumBoats + NumCars; |
INCORRECTint convert(double E); /* function converts feet to angstroms */ |
CORRECTint convert_feet_to_angstroms(double
E); |
FUNCTION DECLARATIONS
Ø Banner comments should
include:
INCORRECT int func(a,b,c,d) int a; float b; char c; double d; return a*b*c*d; |
CORRECT /* func
returns the products of its
arguments. Note: Implicit
conversion to int for b
and d
Inputs: a,b,c,d
Outputs: the product a*b*c*d
*/ int func(int a, int func(float b, int func(char c, int func(double d) { return (a*b*c*d); } /* end func() */ |
INCORRECT int AddNums(int Num1, int Num2) { … } int MultNums(int Num1, int Num2) { … } |
CORRECT int AddNums(int Num1, int Num2) { … } /* end AddNumbers */ /* ------------------------------ */ int MultNums(int Num1, int Num2) { … } /* end SubtractNumbers */ /* ------------------------------ */ |
WHITESPACE
Ø Make opening braces the
last character on their line or else on a line alone.
INCORRECT if (a>b) { b++; }
/* end if a > b */ |
CORRECT if (a>b) {
b++; }
/* end if a > b */ OR
if (a>b) {
b++; }
/* end if a > b */ |
Ø Put the closing braces
of functions on their own lines.
INCORRECT
if (a>b) { b++;
} /* end if a > b */ |
CORRECT
if (a>b) {
b++; }
/* end if a > b */ |
INCORRECT int AddNums(int Num1,int Num2) { … } |
CORRECT int AddNums(int Num1, int Num2) { … } /* end AddNumbers */ |
INCORRECT int count = 0; if (x>count) { printf(“count is too
small\n”); } /* end if for count warning */ |
CORRECT int count = 0; if (x>count) { printf(“count is too
small\n”); } /* end if for count warning */ |
INCORRECT /* this block prevents divide
by zero errors */ if (a==0) {
printf(“a is a bad divisor\n”); } /* end if a is 0 */ |
CORRECT /* this block prevents divide
by zero errors */ if (a==0) {
printf(“a is a bad divisor\n”); } /* end if a is 0 */ |
INCORRECTif (((x>6)&&(y>3))||(flag1&&flag2)) {
z = x+y; } /* end if conditions right */ |
CORRECTif ( ( (x>6) && (y>3) ) ||
(flag1 && flag2) ) {
z = x+y; } /* end if conditions right */ |
COMMENTS
Ø When programming in C
(as you will be in 16.070), always use c-style comments.
INCORRECT# not shell script // not C++ ! not html |
CORRECT/* Ansi C */ |
Ø Banner comments at the
top of the file are important. They should include:
INCORRECT /* Program by J.B. */ int main(void) {
… } /* end main */ |
CORRECT /* Author: Joe Be (joe@mit.edu) Date Begun: 10/31/01 Date Fn1 added: 11/02/01 Dependencies: stdlib.h Function: This file contains a program that adds numbers. */ int main(void) {
… } /* end main */ |
INCORRECT if (a>b) {
…
…
… } |
CORRECT if (a>b) {
…
…
… } /* end if a is greater than b */ |
Ø Comment control flow
structures. Especially explain exit condition for sentinel loops
INCORRECT int Continue = 1; while (Continue) {
… } /* end while to add numbers */ |
CORRECT /* this loop will continue
adding numbers until the
user specifies if should stop,
at which point, continue will
be set to 0
*/ int Continue = 1; while (Continue) {
… } /* end while to add numbers */ |
INCORRECT /********************* /********************* /****add one to j***** /********************* /*********************/ j++; |
CORRECT /* Repeat until valid input */ printf("A number: "); success =
scanf("%d",&num); while(success==0) { fflush(stdin); printf("
*** invalid input\n"); printf("A
number: "); success
= scanf("%d",&num); } /* end while */ |
INCORRECT int NumBoats=0; /*number of boats*/ int Continue=1; /*loop sentinel*/ |
CORRECT int NumBoats = 0; /*number of boats*/ /* expected to be between 0 and 100
it should NEVER be negative
*/ int Continue = 1; /*loop
sentinel*/ /* expected to always be either
0 (false) or 1 (true) */ |
INDENTATION
INCORRECT if (a>b) { printf(“a is bigger\n”); } /* end if a is greater than b */ |
CORRECT if (a>b) {
printf(“a is bigger\n”); } /* end if a is greater than b */ |
Ø Ensure that your
indentations always line up.
INCORRECT if (a>b) {
if (b>c) {
while (q<p) {
q++;
printf(“all set\n”);
} /* end while */ } /* end if b>c */ } /* end if a is greater than b */ |
CORRECT if (a>b) {
if (b>c) {
while (q<p) {
q++;
printf(“all set”);
} /* end while */
} /* end if b>c */ } /* end if a is greater than b */ |
Ø A minimum of two spaces
and maximum of five should be used for your indent.
INCORRECT int main(void){ int a,b; printf("a + b = %d",a+b); return 0; } /* end main */ |
CORRECT int main(void) {
int a,b;
printf("a + b = %d",a+b);
return 0; } /* end main */ |
GENERAL DON’TS
INCORRECTgoto anywhere; |
CORRECT/* implement same situation with a
series of functions
*/ |
Ø Don't use ++ or --
unless it’s on a line by itself or in a
for statement.
INCORRECTx = x-- + ++x; |
CORRECTx++; x = x + x; x--; |
INCORRECTfor (x=0, y=0; x<5; x++) {
printf(“unnecessary operator\n”); } /* end for to make point */ |
CORRECTy=0; for (x=0; x<5; x++) {
printf(“correct usage\n”); } /* end for to make point */ |
INCORRECT(x>y)?x++:y++; |
CORRECTif (x>y) {
x++; } /* end if x>y */ else {
y++; } /* end else x is not grter than y */ |
INCORRECTint * p_Counter; counter=(int *) malloc(sizeof(int)); for (*p_Counter=0; (*p_Counter)<5;
(*p_Counter++) {
printf(“Count: %d”, *p_Counter); } /* end for to count */ |
CORRECTint Counter = 0; for (Counter=0; (Counter)<5;
Counter++) {
printf(“Count: %d”, Counter); } /* end for to count */ |
ADDITIONAL STYLE GUIDES AND RESOURCES