Common mistakes
Below is a list of common errors that programmers often make in C, along with sample code and detailed explanations of why they are mistakes:
Missing semicolon at the end of a statement:
int main() { printf("Hello, world!") return 0; }Explanation: In C, statements must end with a semicolon (
;). Forgetting the semicolon at the end of a statement will result in a compilation error.Using undeclared variables:
int main() { int x = y + 5; return 0; }Explanation: Variables must be declared before they are used. In this example,
yis used without being declared, leading to a compilation error.Misplaced headers:
int main() { #include <stdio.h> printf("Hello, world!"); return 0; }Explanation: Header files (e.g.,
<stdio.h>) should be included at the beginning of the program, not within a function. Placing them inside a function may cause compilation issues.Missing 'return' statement in a non-void function:
int add(int a, int b) { int sum = a + b; }Explanation: In a non-void function, a
returnstatement is required to return a value. The absence of areturnstatement (or a missing value to return) will result in a compilation error.Using assignment operator instead of equality operator:
int main() { int x = 5; if (x = 10) { printf("x is 10"); } return 0; }Explanation: The single equals sign (
=) is an assignment operator. To check for equality, use the double equals sign (==). The code above will assign 10 toxand always execute theprintfstatement.Array index out of bounds:
int main() { int arr[5]; arr[5] = 10; return 0; }Explanation: Array indices in C start from 0. Accessing or modifying an element outside the bounds of the array (in this case, index 5 in an array of size 5) leads to undefined behavior.
Not checking for NULL after dynamic memory allocation:
int *ptr = (int*)malloc(sizeof(int)); *ptr = 5;Explanation: It's essential to check if the memory allocation (
malloc) was successful. IfmallocreturnsNULL, it indicates that the memory allocation failed, and using the pointer without checking can result in runtime errors.Using uninitialized variables:
int main() { int x; printf("%d", x); return 0; }Explanation: Accessing the value of an uninitialized variable leads to undefined behavior. Always initialize variables before using them.
Dividing by zero:
int main() { int a = 10; int b = 0; int result = a / b; return 0; }Explanation: Division by zero is undefined in C and will result in a runtime error. Ensure that the denominator is not zero before performing division.
Using '==` to compare strings:
char str1[] = "Hello"; char str2[] = "Hello"; if (str1 == str2) { printf("Strings are equal"); }Explanation: Strings in C are arrays of characters, and you should use the
strcmpfunction to compare strings. Using==compares the addresses of the arrays, not the content.Missing break statement in switch-case:
int main() { int x = 2; switch (x) { case 1: printf("One"); case 2: printf("Two"); } return 0; }Explanation: Each
caseblock in aswitchstatement should end with abreakstatement. If it's omitted, control will fall through to the nextcase, leading to unintended behavior.Using 'gets' function to read input:
char name[50]; gets(name);Explanation: The
getsfunction is unsafe and can lead to buffer overflow vulnerabilities. Usefgetsinstead, which allows you to specify the maximum number of characters to read.Using the %f format specifier with 'double' in printf:
double num = 3.14; printf("%f", num);Explanation: When printing a
double, use the%lfformat specifier inprintf, not%f.Mixing 'float' and 'double' in comparisons:
float f = 3.14; double d = 3.14; if (f == d) { printf("Equal"); }Explanation: Comparing a
floatand adoubledirectly can lead to unexpected results due to differences in precision. It's safer to compare values of the same type.Using 'sizeof' on a pointer:
int *ptr; printf("%d", sizeof(ptr));Explanation:
sizeofon a pointer returns the size of the pointer, not the size of the data it points to. If you want the size of the pointed data, usesizeof(*ptr).Incorrect format specifier in printf for 'unsigned' types:
unsigned int num = 42; printf("%d", num);Explanation: When printing an
unsignedinteger, use the%uformat specifier, not%d.Using '==` to compare floating-point numbers:
float a = 0.1; float b = 0.2; if (a + b == 0.3) { printf("Equal"); }Explanation: Floating-point numbers may have small rounding errors, and directly comparing them with
==may lead to unexpected results. Use a tolerance or epsilon value for comparisons.Using 'goto' indiscriminately:
int main() { int x = 0; goto label; x = 1; label: printf("%d", x); return 0; }Explanation: The indiscriminate use of
gotocan make code difficult to understand and maintain. In most cases, structured programming constructs like loops and functions are preferred.Assuming 'sizeof' for data types:
int size = sizeof(int); ``
`
Explanation: The size of data types may vary across different systems and compilers. Instead of hardcoding sizes, use sizeof to obtain the size dynamically.
Ignoring the return value of 'scanf':
int num; scanf("%d", &num);Explanation: The
scanffunction returns the number of successfully scanned items. Ignoring this return value may lead to unintended behavior, especially when reading user input.
Incorrect use of the logical AND (
&&) and logical OR (||) operators:int x = 5; if (x > 0 && x < 10 || x == 20) { printf("Condition met"); }Explanation: The logical AND (
&&) has higher precedence than the logical OR (||). To ensure correct evaluation, use parentheses to explicitly specify the grouping of conditions.Using 'printf' with the wrong format specifier:
char ch = 'A'; printf("%d", ch);Explanation: When printing a character with
printf, use the%cformat specifier, not%d.Incorrectly initializing a string:
char str[5] = "Hello";Explanation: Strings in C require space for the null terminator (
'\0'). In this case, the array size should be at least 6 to accommodate the characters in "Hello" plus the null terminator.Using 'sizeof' on an array parameter:
void printArray(int arr[]) { printf("%d", sizeof(arr)); }Explanation: In function parameters, an array decays into a pointer. Using
sizeofon such a parameter gives the size of a pointer, not the size of the array. Pass the array size explicitly or use a different data structure likestd::vectorin C++.Missing 'return' statement in a non-void function:
int divide(int a, int b) { if (b == 0) { printf("Error: Division by zero"); } }Explanation: All code paths in a non-void function must have a
returnstatement. The absence of areturnstatement, especially in conditional blocks, can lead to undefined behavior.Misusing the comma operator:
int x = 5, y = 10, z; z = x, y;Explanation: The comma operator evaluates expressions from left to right and returns the result of the rightmost expression. In this case,
zwill be assigned the value ofx, noty.Incorrect use of the 'typedef' keyword:
typedef int* IntPtr; int x, y; IntPtr ptr = &x, y;Explanation: The
typedefdeclaration applies only to the variableptr, noty. To declare multiple variables of the same type, use separate declarations or a structure.Inconsistent use of 'const':
const int a = 10; int* const ptr = &a;Explanation: Inconsistency in the use of
const. Here,ptris declared as a constant pointer, but it is assigned the address of a non-constant variable. Ensure consistency in the use ofconst.Using 'rand()' without seeding:
int randomNum = rand();Explanation: The
rand()function generates pseudo-random numbers, but it requires seeding usingsrand()to produce different sequences. Without seeding, the same sequence of numbers will be generated on each program run.Assuming 'sizeof' for structure padding:
struct Example { char a; int b; }; printf("%d", sizeof(struct Example));Explanation: The size of a structure may include padding for alignment. Instead of assuming the exact size, use
sizeofto obtain the size dynamically.
Using 'switch' with non-integral or non-enum types:
double grade = 85.5; switch (grade) { case 90.0: printf("A"); break; // other cases... }Explanation: The
switchstatement in C can only be used with integral types or enumerated types. Using it with non-integral types, likedouble, will result in a compilation error.Ignoring the return value of 'fclose':
FILE *file = fopen("example.txt", "r"); // operations on file... fclose(file);Explanation: The
fclosefunction returns an integer value that indicates the success or failure of the operation. Ignoring this return value may lead to issues in handling file closures.Using 'printf' without format specifiers:
int x = 42; printf(x);Explanation: The
printffunction expects format specifiers to match the types of the provided arguments. In this case,%dshould be used as a format specifier for the integer variablex.Using a reserved keyword as an identifier:
int double = 10;Explanation: Identifiers in C cannot be reserved keywords. In this example, using "double" as a variable name is invalid because "double" is a keyword in C.
Missing 'break' statement in the 'default' case:
int option = 2; switch (option) { case 1: printf("Option 1"); break; case 2: printf("Option 2"); // missing break statement default: printf("Default option"); }Explanation: The
breakstatement is missing in thecase 2block. Without it, control will fall through to thedefaultcase, leading to unintended behavior.Using 'strcpy' without checking buffer size:
char destination[10]; char source[] = "Hello, World!"; strcpy(destination, source);Explanation: The
strcpyfunction does not check the size of the destination buffer. If the source string is longer than the destination buffer, it may lead to buffer overflow and undefined behavior. Usestrncpywith explicit buffer size instead.Incorrect use of the conditional (ternary) operator:
int x = 5, y = 10; int result = x > y ? x : y > 0 ? y : 0;Explanation: The conditional operator (
? :) has right-to-left associativity. To avoid ambiguity, use parentheses to explicitly specify the grouping of conditions and expressions.Assuming ASCII values for character manipulation:
char ch = 'A'; ch += 1;Explanation: While ASCII values are commonly used, assuming a specific character encoding can lead to portability issues. Use character functions or constants from the
<ctype.h>header for safer character manipulation.Using 'sizeof' with variable-length arrays (VLAs):
int size = 5; int arr[size]; printf("%d", sizeof(arr));Explanation: The
sizeofoperator may not behave as expected with variable-length arrays (VLAs). Instead of relying onsizeoffor VLAs, consider using a constant or dynamic memory allocation.Incorrectly using the '&&' operator in place of '||':
int x = 5; if (x > 0 && x < 2) { printf("Condition met"); }Explanation: Using
&&instead of||in a conditional statement may lead to unexpected behavior. Ensure that the logical operators are used correctly based on the intended logic.