Good Programming Practice: Version 1.0
Written By:X_console
shellscope@yahoo.com
Continued...
Was there a better way of writing this? You bet. Use the "switch" case
statement instead. Switch is neat:
switch(a)
{
case 0: a++;
return(a);
case 1: a += 5;
return(a);
case 2: a += 10;
return(a);
case 3: a += 20;
return(a);
default: exit(1);
}
Here we see the various cases and what they do depending on the value of
"a". When a no-match is found, it automatically goes to the default
action, which in this case is to exit.
Abusing Nesting
Now we're going to talk about how people abuse nesting. It is considered
bad programming practice to have more than three levels of nesting. Why?
It causes confusion, and the code is hard to read. Here's an example in:
int a = 10;
int b = 20;
int c = 30;
int d = 40;
if(a == 10)
{
a = a + d;
if(b == 20)
{
b = b + a;
if(c != b)
{
c = c + 1;
if(d > (a + b))
printf("Made it all the way to the bottom!\n");
}
}
}
Obviously this is exaggerating a little, but you'd be surprised how some
people actually do this.
So how do we fix it? One way, is perhaps to break it up with functions:
void next(int a, int b, int c, int d)
{
if(c != b)
{
c = c + 1;
if(d > (a + b))
printf("Made it all the way to the bottom!\n");
}
}
int main()
{
int a = 10;
int b = 20;
int c = 30;
int d = 40;
if(a == 10)
{
a = a + d;
if(b == 20)
{
b = b + a;
next(a, b, c, d);
}
}
return(0);
}
Okay, this took a bit more work, but now your code is structured and
easier to read. Sometimes it takes a little bit more code in order to
make the overall code easier to understand. Don't be lazy.
Commenting Code
Commenting code is good programming practice. Always comment statements
or variables that you think people will have trouble understanding:
int x = 100;
int y = 1000;
if(x < y)
a = 0;
else
a = 1;
Can you tell what this program does? What it's purpose is? No. Not
without knowing what the variables x, y, and a represent. Now let's
comment it:
/*
* a program that checks for profit and loss:
*/
int x = 100;
/* x is the total amount of money gained from selling books */
int y = 1000
/* y is the cost spent to manufacture the books */
int a;
/* determines whether we made a profit or loss */
/* check to see if x is less than y: */
if(x < y)
/* we made a loss. let the number 1 stand for loss:
a = 1;
else
/* we made a profit. let the number 0 stand for profit */
a = 0;
Now even if you don't program in C, you already know what this program
does. You have an idea of what each statement does, and you know what each
variable stands for. I said that commenting is good. But over commenting
your code is bad. You use comments to make certain code easier to
understand, but you don't use comments to tell a story:
int profit = 1; /* profit is equal to 1 */
int loss = 0; /* loss is equal to 0 */
/* if profit equals to 1: */
if(profit == 1)
/* print "We made a profit!" */
printf("We made a profit!\n");
/* else: */
else
/* print "We made a loss!" */
printlf("We made a loss!\n");
This is an amazing waste of time. You're telling the programmer the
obvious. Commenting is best used when you're declaring variables, and when
you're performing some operation on variables. You need to tell the
programmer what each variable represents, and what happens to each
variable. You need to tell the programmer what your program does, and how
it does what it does. You need to tell the programmer what each function,
method, procedure, and error code does. The programmer does not want to
guess.
Naming
Always try to name your variables, functions, methods, procedures, unions,
structures, and classes by what it is they represent. This means that
naming your variables "x", "y", and "z" is a bad idea. Now you're probably
screaming "HYPOCRITE", but hang on. The reason I used one letter variables
is because I'm just doing examples. When I write actual programs, I use
meaningful names. So. Let's take a look at this code:
void x(int a, int b)
{
int z;
z = a + b;
printf("z is %d\n", z);
}
Here we have an idea of what procedure x does, but we don't know what it
represents. We also do not know what a, b, and z represent. Let's modify
it a litte:
void sum_of_ages(int jacks_age, int jills_age)
{
int total_age;
total_age = jacks_age + jills_age;
print("total_age is %d\n", total_age);
}
Now here, the code is uncommented, but because of the way you've named the
variables, anyone who looks at your code, can get a general idea of what
you're trying to do here. We know what each variable represents and we
know for sure what the function's supposed to do. A program with well
named functions and variables might not need a lot of commenting.
Checking The Buffer
This is important. When you're writing code, make sure to always check for
buffer overflows. Make sure the data that's being put into your array does
not exceed the amount of data the array can hold. A lot of programs fail
to do this and they are often the cause of many system break-ins because a
programmer can use a buffer overflow to run priveleged programs. Let's
look at a C program that takes input from a user:
char city[10];
/* array that holds the name of a city */
printf("Enter a city name: ");
scanf("%s", city);
printf("City is %s\n", city);
Now this assumes that the city name is 9 elements long (the 10th element
is the terminating null character: \0). So what happens when the user
enters a name longer than 9 characters? Nothing might happen, or the
program might crash, or overwrite data beyond the buffer. Either way,
don't risk it. Check the input length:
char city[10];
/* array that holds the name of a city */
printf("Enter a city name: ");
fgets(city, sizeof(city), stdin);
printf("City is %s\n", city);
What happens here is that if the user enters more than what the buffer can
hold, the extra input is truncated off.
Never Trust The User
This is an important rule. Do not trust the people who will be
using your programs. Treat them as people who are looking for ways to
crash your program, so make sure you have a counter attack to their
actions. For instance, the program we did above that was succeptible to a
buffer overflow, we countered it by checking the length of the string
input by the user. When using languages like C which require you to
specify data types, make sure you check that the data type the user
inputs is the data type that you're using. Otherwise, your program could
very well crash. The bottom line is that you implement error checking.
Use your debugger to monitor what goes on when your program runs, for
instance, what happens to the variables. I know that error checking takes
a lot of time, but if you don't want your program to crash, it's the only
way.
Conclusion
Well that's it for now. As soon as I think up of more stuff to write, I'll
update this document. In the meantime, try to practice good programming.
It really helps in the long run, especially when you need to maintain
code, and it makes it easy for your fellow programmers to read what you
write. If you find any mistakes in this article, or have any constructive
criticisms, I welcome your feedback.
X_console
shellscope@yahoo.com
|