0% found this document useful (0 votes)
51 views5 pages

Chasing The Bugs: Int Choice Scanf (" %D ", Choice)

This document provides a list of common programming mistakes made by C programmers. These include omitting the ampersand before variables in scanf(), using the assignment operator = instead of equality operator == in conditions, ending loops with semicolons, omitting breaks in switch statements, using continue in switch statements, mismatching argument types in functions, omitting return types from functions, inserting semicolons after macro definitions, omitting parentheses around macro expansions, leaving blanks between macro names and parameters, using expressions with side effects in macros, confusing character and string constants, forgetting array bounds, omitting null terminators in character arrays, confusing operator precedence, mistaking -> and . with structures, forgetting far pointers, and exceeding integer and

Uploaded by

harshg_nitc3353
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
51 views5 pages

Chasing The Bugs: Int Choice Scanf (" %D ", Choice)

This document provides a list of common programming mistakes made by C programmers. These include omitting the ampersand before variables in scanf(), using the assignment operator = instead of equality operator == in conditions, ending loops with semicolons, omitting breaks in switch statements, using continue in switch statements, mismatching argument types in functions, omitting return types from functions, inserting semicolons after macro definitions, omitting parentheses around macro expansions, leaving blanks between macro names and parameters, using expressions with side effects in macros, confusing character and string constants, forgetting array bounds, omitting null terminators in character arrays, confusing operator precedence, mistaking -> and . with structures, forgetting far pointers, and exceeding integer and

Uploaded by

harshg_nitc3353
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 5

Chasing The Bugs 

C Programmers are great innovators of our times. Unhappily, among their most enduring
accomplishment are several new techniques for wasting time. There is no shortage of horror
stories about programs that took twenty times to 'debug' as they did to 'write'. And one hears
again and again about programs that had to be rewritten all over again because the bugs
present in it could not be located.

A typical C programmer's morning after is red eyes, blue face and a pile of crumpled
printouts and dozens of reference book all over the floor. Bugs are C programmer's birth
right. But how do we chase them away. No sure-shot way for that. I thought if I make a list of
more common programming mistakes it might be of help. They are not arranged in any
particular order. But as you would realize surely a great help!

a. Omitting the ampersand before the variables used in scanf(  ).

For example,
int choice ;
scanf ( " %d ", choice ) ;
 
Here, the & before the variable choice is missing. Another common mistake with scanf( )
is to use blanks either just before the format string or immediately after the format string
as in,
int  choice ;
scanf ( " %d ", choice ) ;
 
Note that this is not a mistake, but till you don't understand scanf( ) thoroughly, this is
going to cause trouble. Safety is in eliminating the blanks. Thus, the correct from would
be,
int choice ;
scanf ( " %d ", &choice ) ;

b. Using the operator = instead of the operator ==.

What do you think will be the output of the following program:


main( )
{
int i = 10 ;
while ( i = 10 )
{
printf ( "got to get out" ) ;
i++ ;
}
}
 
At first glance it appears that the message will be printed once and the control will come
out of the loop since i becomes 11. But, actually we have fallen in an indefinite loop.
This is because the = used in the condition always assigns the value 10 to i, and since i
is non-zero the condition is satisfied and the body of the loop is executed over and over
again.
c. Ending a loop with a semicolon. Observe the following program.

main(  )
{
int j = 1 ;
while ( j <= 100 ) ;
{
printf ( "\nCompguard" ) ;
j++ ;
}
}
 
Inadvertently, we have fallen in an indefinite loop. Cause is the semicolon after while.
This in effect makes the compiler feel that you wanted the loop to work in the following
manner:
while ( j <= 100 ) ;
 
By all means an indefinite loop since j never gets incremented and hence eternally
remains less that 100.

d. Omitting the break statement at the end of a case in a switch statement. Remember
that if a break is

not included at the end of a case then execution will continue into the next case.
 
main( )
{
int ch = 1 ;
switch ( ch )
{
case1 :
printf ( "\nGoodBye" ) ;
case 2 :
printf ( "\nLieutenant" ) ;
}
}
 
Here, since the break has not been given after the printf( ) in case 1, the control runs
into case 2 and executes the second printf( ) as well. However, this sometimes turns out
to be a blessing in disguise, especially, in cases when we are checking whether the
values of a variable equals a capital letter or a small case letter.

e. Using continue in a switch. It is a common error to believe that the way the keyword
break is used with while, for, do-while and a switch, similarly the keyword continue can
also be used with them. Remember, continue works only in loop, never with a switch.

f. A mismatch in the number, type and order of actual and formal argument.

yr= romanise ( year, 1000, 'm' ) ;


 
Here, three arguments in the order int, int and char are being passed to romanise( ).
When romanise( ) receives these arguments they must be received in the same order by
the formal arguments. A careless mismatch might give strange results.
g. Omitting provisions for returning non-integer value from a function.

If we make the following function call, 


area = area_circle ( 1.5 ) ;
 
then while defining area_circle( ) function later in the program, care should be taken to
make it capable of returning a floating point value. Note that unless otherwise
mentioned, the compiler will assume that function returns a value of the type int.

h. Inserting a semicolon at the end of a macro definition. How do you recognize a C


programmer? Ask him to write a paragraph in English and watch whether he ends each
sentence with a semicolon. This usually happens because a C programmer becomes
habitual to ending all statements with a semicolon. However, a semicolon at the end of
a macro definition might create a problem.

For example,
#define UPPER 25;
 
would lead to a syntax error if used in an _expression such as 
if ( counter == UPPER )
 
This is because on preprocessing the if statement would take the form
if ( counter == UPPER; )

i. Omitting parentheses around a macro expansion.

#define SQR(x) x*x


main( )
{
int a ;
a=25 / SQR ( 5 ) ;
printf ( "\n%d", a ) ;
}
 
In this example we expect the value of a to be 1, whereas it turns out to be 25. This so
happens because on
preprocessing the arithmetic statement takes the following form:
a = 25 / 5 * 5 ;

j. Leaving a blank between the macro template and the macro expansion.

#define ABS (a) ( a=0 ? a : -a )


 
Here, the space between ABS and (a) makes the preprocessor believe that you want to
expand ABS into (a), which is certainly not what we want.

k. Using an _expression that has side effects in a macro call.

#define SUM(a) (a+a)


main( )
{
int w, b = 5;
w= SUM ( b++ ) ;
printf ( "\n%d", w ) ;
}
On preprocessing the macro would be expanded to, w=(b++) +(b++); If you are wanting
to first get sum 5 and 5 and them increment b to 6, that would not happen using the
above macro definition.

l. Confusing a character constant and a character string

In the statement
ch = 'z';
 
a single characters is assigned to ch. In the statement
ch = "z"
a pointer to the characters string "a" is assigned to ch.
 
Note that in the first case, the declaration of ch would be,
char ch ;
 
whereas in the second case it would be,
char*ch;

m. Forgetting the bounds of an array.

main( )
{
int num[50], i ;
for ( i =1; i <= 50 ; i++ )
num[i] = i * i ;
}
 
Here, in the array num there is no such element as num[50]. Since array counting
begins with 0 and not 1. Compiler would give no warning if our program exceeds the
bounds. If not taken care of, in extreme cases the computer might even hang. 

n. Forgetting to reserve an extra location in a character array for the null terminator.
Remember each characters array ends with a '\0', therefore its dimension should be
declared big enough to hold the normal characters as well as the '\0'.

For example, the dimension of the array word[ ] should be 9 if a string "Jamboree" is to
be stored in it.

o. Confusing the precedence of the various operations.

main( )
{
char ch ;
FILE *fp ;
fp = fopen ( "text.c", "r" ) ;
while ( ch = getc ( fp ) != EOF )
putch ( ch ) ;
fclose ( fp ) ;
}
 
Here, the value returned by getc( ) will be first compared with EOF, since != has a higher
priority than =. As a result, the value that is assigned to ch will be the true/false result of
the test: 1 if the values returned by getc( ) is not equal to EOF, and 0 otherwise. The
correct from of the above while would be,  
while ( ( ch = getc ( fp ) ) != EOF )
putch ( ch ) ;

p. Confusing the operator -> with the operator '.', while referring to a structure element.
Remember, on the left of the operator '.' only a structure variable can occur, whereas on
the left of the operator -> only a pointer to a structure can occur. 

main( )
{
struct emp
{
char name[35] ;
int age ;
};
struct emp e = {"Dubhashi", 40 } ;
struct emp *ee ;
printf ( "\n%d", e.age ) ;
ee = &e ;
printf ( "\%d", ee -> age ) ;
}

q. Forgetting to use the far keyword for referring memory location beyond the data
segment.

main( )
{
unsigned int*s; s = 0x413 ;
printf ( "\n%d", *s ) ;
}
 
Here, it is necessary to use the keyword far in the declaration of variable s, since the
address that we are storing in s (0x413) is address of a location present in BIOS Data
Area, which is far away from the data segment. Thus, the correct declaration would be
unsigned int far*s ; 

r. Exceeding the range of integers and chars.

main( )
{
char ch ;
for ( ch = 0 ; ch <= 255 ; ch++ )
printf ( "\n%c %d, ch, ch ) ;
}
 
Can you believe that this is an indefinite loop? Probably, a closer look would confirm it.
Reason is, ch has been declared as a char and the valid range of char constant is -128
to +127. Hence, the moment ch tries to become 128 (through ch++), the value exceeds
the character range, therefore the first number from the negative side of the range, i.e.
-128, gets assigned to ch. Naturally the condition is satisfied and the and the control
remains within the loop eternally.

You might also like