Common Programming Mistakes

THE FOLLOWING LIST SUMMARIZES SOME OF the more common programming mistakes made in C.They are not arranged in any particular order. Knowledge of these mistakes will hopefully help you avoid them in your own programs.

1. Misplacing a semicolon.

Example

if ( j == 100 );

j = 0;

In the previous statements, the value of j will always be set to 0 due to the misplaced semicolon after the closing parenthesis. Remember, this semicolon is syntactically valid (it represents the null statement), and, therefore, no error is produced by the compiler.This same type of mistake is frequently made in while and for loops.

2. Confusing the operator = with the operator ==.

This mistake is usually made inside an if, while, or do statement.

Example

if ( a = 2 )

printf ("Your turn.\n");

The preceding statement is perfectly valid and has the effect of assigning 2 to a and then executing the printf call.The printf function will always be called because the value of the expression contained in the if statement will always be nonzero. (Its value will be 2.)

3. Omitting prototype declarations.

Example

result = squareRoot (2);

If squareRoot is defined later in the program, or in another file, and is not explicitly declared otherwise, the compiler assumes that the function returns an int.

Furthermore, the compiler converts float arguments to double, and _Bool, char,and short arguments to int. No other conversion of arguments is done.

Remember, it’s always safest to include a prototype declaration for all functions that you call (either explicitly yourself or implicitly by including the correct header file in your program), even if they’re defined earlier.

4. Confusing the precedences of the various operators.

Examples

while ( c = getchar () != EOF )

...

if ( x & 0xF == y )

...

In the first example, the value returned by getchar is compared against the value EOF first.This is because the inequality test has higher precedence than the assignment operator.The value that is therefore assigned to c is the TRUE/FALSE result of the test: 1 if the value returned by getchar is not equal to EOF, and 0 otherwise.

In the second example, the integer constant 0xF is compared against y firstbecause the equality test has higher precedence than any of the bitwise operators.

The result of this test (0 or 1) is then ANDed with the value of x.

5. Confusing a character constant and a character string.

In the statement

text = 'a';

a single character is assigned to text. In the statement

text = "a";

a pointer to the character string "a" is assigned to text.Whereas, in the first case,text is normally declared to be a char variable, in the second case, it should be declared to be of type "pointer to char".

6. Using the wrong bounds for an array.

Example

int a[100], i, sum = 0;

...

for ( i = 1; i <= 100; ++i )

sum += a[i];

Valid subscripts of an array range from 0 through the number of elements minus one.Therefore, the preceding loop is incorrect because the last valid subscript of a is 99 and not 100.The writer of this statement also probably intended to start with the first element of the array; therefore, i should have been initially set to 0.

7. Forgetting to reserve an extra location in an array for the terminating null character of a string.

Remember to declare character arrays so that they are large enough to contain the terminating null character. For example, the character string "hello" would require six locations in a character array if you wanted to store a null at the end.

8. Confusing the operator -> with the operator . when referencing structure members.

Remember, the operator . is used for structure variables, whereas the operator -> is used for structure pointer variables. So, if x is a structure variable, the notation x.m is used to reference the member m of x. On the other hand, if x is a pointer to a structure, the notation x->m is used to reference the member m of the structure pointed to by x.

9. Omitting the ampersand before nonpointer variables in a scanf call.

Example

int number;

...

scanf ("%i", number);

Remember that all arguments appearing after the format string in a scanf call must be pointers.

10. Using a pointer variable before it’s initialized.

Example

char *char_pointer;

*char_pointer = 'X';

You can only apply the indirection operator to a pointer variable after you have set the variable pointing somewhere. In this example, char_pointer is never set pointing to anything, so the assignment is not meaningful.

11. 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 continues into the next case.

12. Inserting a semicolon at the end of a preprocessor definition.

This usually happens because it becomes a matter of habit to end all statements with semicolons. Remember that everything appearing to the right of the defined name in the #define statement gets directly substituted into the program. So the definition

#define END_OF_DATA 999;

leads to a syntax error if used in an expression such as

if ( value == END_OF_DATA )

...

because the compiler will see this statement after preprocessing:

if ( value == 999; )

...

13. Omitting parentheses around arguments in macro definitions.

Example

#define reciprocal(x) 1 / x

...

w = reciprocal (a + b);

The preceding assignment statement would be incorrectly evaluated as

w = 1 / a + b;

14. Leaving a blank space between the name of a macro and its argument list in the #define statement.

Example

#define MIN (a,b) ( ( (a) < (b) ) ? (a) : (b) )

This definition is incorrect, as the preprocessor considers the first blank space after the defined name as the start of the definition for that name. In this case, the statement

minVal = MIN (val1, val2);

gets expanded by the preprocessor into

minVal = (a,b) ( ( (a) < (b) ) ? (a) : (b) )(val1,val2);

which is obviously not what is intended.

15. Using an expression that has side effects in a macro call.

Example

#define SQUARE(x) (x) * (x)

...

w = SQUARE (++v);

The invocation of the SQUARE macro causes v to be incremented twice because this statement is expanded by the preprocessor to

w = (++v) * (++v);

【摘自《Programming in C》】

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • **2014真题Directions:Read the following text. Choose the be...
    又是夜半惊坐起阅读 9,968评论 0 23
  • 有的时候,真的不知道自己为什么这么多愁善感,每次听到喜欢的歌都想分享给别人听,但是即使再好听的歌,在别人听来也可能...
    岛屿心情阅读 339评论 0 0
  • 大江东去,浪淘尽,剩下的银贝金珠,便是我们民族璀璨的中华文化。在这片古老的华夏大地上,兴衰更迭。随着潮起潮落...
    纪榣阅读 286评论 1 3
  • 2016-05-19 18:44:41121 “自序:不一样的教育”读后感 “莎士比亚说,世界是个...
    暖阳西子阅读 444评论 0 0
  • 她是个漂亮的姑娘。 我见她第一眼的时候就这样觉得。现在也还会絮絮叨叨地告诉别人,我认识一个很漂亮的姑娘,用很骄傲的...
    NiPai阅读 322评论 0 0