COMP2004
Programming Practice
2002 Summer School
Kevin Pulo
School of Information Technologies
University of Sydney
(page 1)
Using &
- & has 2 different meanings depending on where it's used
- In front of an object
- Takes the address
- int* p = &i;
- In a function parameter definition
- Pass by reference
- int sum(std::vector &v)
(page 2)
Code style
- Indenting
- Whitespace
- Identifiers
- Structure
- Comments
- Bracketing
- In all cases aim to make your code
- Easily readable
- Consistent
(page 3)
Indenting
- By far the most important
- Choose a certain number of spaces and stick with it
- Common ones are 8, 4 and 2
- Indent code inside control structures
- functions, if(), while(), for(), etc
(page 4)
Bad Indenting 1
double a_function(int a) {
int b = 0;
double c;
while(b < 100) {
if (a == b) {
c = 34.2; }
else
{ c = 12.8;
}
}
}
(page 5)
Bad Indenting 2
double a_function(int a) {
int b = 0;
double c;
while(b < 100) {
if (a == b) {
c = 34.2; }
else
{c = 12.8;
}
}
}
(page 6)
Good Indenting
double a_function(int a) {
int b = 0;
double c;
while(b < 100) {
if (a == b) {
c = 34.2;
} else {
c = 12.8;
}
}
}
(page 7)
Whitespace
- Groups related code together
- Vertical
- Blank lines between functions, code paragraphs
- Horizontal
- Spaces around operators, brackets, etc
(page 8)
Bad Vertical Whitespace
unsigned int numDigits(unsigned long x) {
return static_cast(log10(x)) + 1;
}
void getDigits(std::vector &digits, unsigned long number) {
unsigned int i, n;
n = numDigits(number);
digits.resize(n);
for (i = n - 1; i > 0; i--) {
digits[i] = number % 10;
number = number / 10;
}
digits[i] = number;
}
int main() {
unsigned int number;
while (std::cin >> number) {
std::vector digits;
getDigits(digits, number);
std::cout << digits[0];
for (int i = 1; i < digits.size(); i++)
std::cout << ", " << digits[i];
std::cout << std::endl;
}
}
(page 9)
Good Vertical Whitespace
unsigned int numDigits(unsigned long x) {
return static_cast(log10(x)) + 1;
}
void getDigits(std::vector &digits, unsigned long number) {
unsigned int i, n;
n = numDigits(number);
digits.resize(n);
for (i = n - 1; i > 0; i--) {
digits[i] = number % 10;
number = number / 10;
}
digits[i] = number;
}
int main() {
unsigned int number;
while (std::cin >> number) {
std::vector digits;
getDigits(digits, number);
std::cout << digits[0];
for (int i = 1; i < digits.size(); i++)
std::cout << ", " << digits[i];
std::cout << std::endl;
}
}
(page 10)
Horizontal Whitespace
- if ((d >= 1) && (d <= maxDays))
- for(i=s.size()-1;i>0;--i)
- for (i=s.size()-1; i>0; --i)
- for ( i = s.size() - 1 ; i > 0 ; --i )
(page 11)
Identifiers
- Names of variables, functions, enums, etc
- Descriptive and concise
- Nouns for variables, verbs for functions
- Singular for variables, plurals for collections
- Consistent scheme for multiple-word identifiers
multipleWordIdentifiermultiple_word_identifier
(page 12)
Bad Identifiers
- Anything one letter long (except i as a loop iterator)
- Identifiers which vary by only 1 character
- eg: item0, item1, item2, ...
- If these items are related, consider an array/vector instead
- eg: item[0], item[1], item[2], ...
(page 13)
Bad Identifiers
- Unnecessary abbreviations and spelling mistakes
- eg: nmItms, piont
- better: numItems, point
- Unnecessarily long/verbose
- eg: number_of_elements_in_array
- better: num_elems
(page 14)
Structure
- High cohesion
- Each function performs exactly one task
- Low coupling
- Each function has minimal reliance on other functions
- Low cohesion and high coupling make code hard to read and maintain
- eg. solution for Week 1 Wed Q4
(page 15)
Comments
- Describe the code's purpose / meaning
- Don't just restate the code in English
- i++; // Increment i
- i++; // Make i be 1 bigger
- i++; // Move to next vector element
(page 16)
Comments
- Each of these should have a comment
- Entire program
- Every function (except main())
- Mention parameters and return value
- Every large code paragraph
- Every important variable
- Complex or hard-to-understand statements and expressions
(page 17)
Comment syntax
int i; // Comment to end-of-line
int i; /* Comment with begin and end */
int i;
#if 0
Large block comment
#endif
(page 18)
Comment syntax
- /* */
- Can appear anywhere
- Not nestable
if ((d >= 1) && (d /*<=*/ maxDays)) if ((d >= 1) /* && (d /*<=*/ maxDays)*/) if ((d >= 1) maxDays)*/)
(page 19)
Comment syntax
- #if 0
- #endif
- Must appear on own line
- Nestable
- Most useful for removing large sections of code while debugging/ testing
(page 20)
Bracketing
- Several styles - just be consistent
if (a == b) do_something();
if (b == c)
{
part_1();
part_2();
}
else
something_else();
(page 21)
Another bracketing style
if (a == b) {
do_something();
}
if (b == c) {
part_1();
part_2();
} else {
something_else();
}
(page 22)
Simple g++ errors
- Line number usually most useful
1: #include
2: int main() {
3: int i = 42;
4: int* p = *i;
5: cout << &p << endl;
6: }
bash$ g++ -Wall -g -o prog prog.ccprog.cc: In function `int main()':
prog.cc:4: invalid type argument of `unary *'
(page 23)