Who discovered the C language 1

The 12 most common programming mistakes

  • The beginning and end of comments must be correctly labeled.
    Beginning of comment: / *
    End of comment: * /
  • The assignment operator = is often confused with the test operator ==.
    This error occurs so often because other programming languages ‚Äč‚Äčalso use = as a test operator. In addition, the compiler often does not detect this error because an assignment has a value and can therefore appear in a comparison expression. For example: if (number = 9) {/ * wrong * / number = 0; } This sequence is syntactically correct, compiles without errors, but will not do the desired thing during processing. Instead of assigning the value 0 to the variable number, if it is equal to 9, number is always set to 0 because the assignment always returns the logical value!
    You can remedy this by getting used to always write down the value against which the comparison is being made first. So: if (9 == number) {/ * correct * / number = 0; } If you accidentally write = instead of ==, the compiler will output an error message.
  • Error in assignments in comparison expressions.
    If the brackets around an assignment are forgotten, the comparison is processed first and its result assigned. This is syntactically correct and is not noticed by the compiler. For example: while (ch = getchar ()! = EOF) / * false * / This will assign the value 1 for TRUE to the variable ch until getchar () returns EOF. Then ch receives the value 0 for FALSE.
    However, the programmer probably wanted the variable ch to be assigned the character returned by getchar ()! The correct syntax for this is: while ((ch = getchar ())! = EOF) / * correct * /
  • Error using arrays.
    The smallest index of an array in C is 0. That is, the declaration int a [10]; defines ten array elements a [0], a [1], ..., a [9]. An attempt to access a [10] is not noticed either by the compiler or by the runtime system: for (i = 0; i <= 10; i ++) / * wrong! The highest index is 9 * / a [i] = i; This example will assign the value 10 to the variable a [10] at runtime. However, since the variable a [10] does not exist, another variable may be overwritten.
    The lack of checking of field boundaries during runtime is often exploited by hackers to generate (un) controlled program crashes and represents a critical security hole in network software. Such errors can be discovered with special memory debuggers such as Dmalloc or Bounds Checker.
  • Brackets when calling functions without parameters.
    If, for example, there is a parameterless function getValue, the function call is x = getValue; / * wrong * / wrong.
    The correct call would be x = getValue (); /* correct */
  • Error when passing a pointer to a function.
    A convert function is available as void convert (int * px); declared. Since the parameter px is a pointer to an integer variable, the function call must also be made with a pointer as a parameter. For example: int result; convert (& result); A typical mistake is that the address operator & is forgotten here.
  • Functions must be declared!
    If a function is not declared before it is used, automatically int accepted as the return type. For example: double a; a = getdouble (); / * wrong * / Here a becomes a int instead of the expected double assigned because the compiler assumes that getdouble () is a int returns. To correct this, the function must first be declared (this is also known as a prototype): double getdouble (); double a; a = getdouble (); /* correct */
  • The 'break' in 'switch' statements must not be forgotten!
    If the break is forgotten, the program execution continues until the next break or the end of the switch statement. Example: switch (weekday) {case MONDAY: printf ("Start a new week"); case TUESDAY: / * no break here * / case FRIDAY: workday ++; break; default: weekday ++; } If weekday is MONDAY, the code for TUESDAY and FRIDAY is also executed, since there is no break after MONDAY and TUESDAY. If this behavior is intended by the programmer, it should be commented as in the example.
  • Use of side effects in expressions.
    The use of side effects ("to save paperwork") can lead to undesired results. Example: a [n] = n ++; Is equivalent to either: a [n] = n; n = n + 1; or to: a [n + 1] = n; n = n + 1; Which of the two cases occurs depends on the compiler.
  • Type conversions failed.
    The conversion of char to int hangs similar to bit shift operations char depends on whether the type char as signed or unsigned is defined. This in turn depends on the compiler or a compiler switch. Example: char a; a = 228; / * iso code for the german a-umlaut * / printf ("% d \ n", a); / * implicit conversion to int * / Either -28 or 228 is output. With the GNU compiler gcc this behavior can be controlled by using the command line switch -funsigned-char or -fsigned-char.
  • Brackets when using pointers and increment / decrement operators.
    Example: char line [80]; * lp = line; ch = * lp ++; / * the same as * (lp ++) * / In this example, ch is assigned the character that lp points to. Then lp is incremented. However, if you use ch = (* lp) ++; so ch is also assigned the character to which lp points. Afterwards, however, the character to which lp points is not incremented, but rather the lp!
  • The logical operators && and || must not be used with the bit operators & and | be confused!