Today, I summarized some common errors in C + + programs, which we should try our best to avoid
1. Operation sequence error
Let's look at a procedure for judging odd and even numbers:
#include <stdio.h> int main(int argc, char** argv) { int n = 0; printf("Input a natural number:\n"); while (1 == scanf("%d", &n)) { if (1 & n == 0) { // Notice here! printf("Even\n"); } else { printf("Odd\n"); } } return scanf("%*s%*s"); }
Compile without error, but run to get the wrong result;
"Even" will be output only when 0 is input, and "Odd" will be output in other cases
We note that = = is a relational operation, while & is a bit operation, and the former takes precedence over the latter
"1 & n == 0" is actually equivalent to "1 & (n == 0)", which is equivalent to "n == 0";
Therefore, we should change the condition in if to "(1 & n) = = 0", or "! (1 & n)"
Some ides that are strictly checked will give warning s in such places. It is suggested that we add parentheses
2. Subscript out of bounds error
When using arrays, we may have used wrong subscripts, resulting in illegal access to memory
In the following case, no error will be reported during compilation and no exception will be thrown during operation, but there are problems:
#include <stdio.h> #include <time.h> #include <random> #define LEN 10 int main(int argc, char** argv) { srand(time(NULL)); int* p = new int[LEN]; int i = 0; for (; i < LEN; ++i) { p[i] = rand() % 50; } while (1 == scanf("%d", &i)) { // There should be something extra; printf("p[%d]= %d\n", i, p[i]); } delete[] p; return scanf("%*s"); }
The original intention of this program is to generate 10 random numbers within a certain range, put them in the array and access them through subscripts;
However, after entering the subscript, its legitimacy is not checked, which may cross the boundary;
Therefore, the correct writing should judge whether i is a legal subscript before printf
There's another way,
We use vector instead of array and at function instead of subscript. The vector is defined in < vector >, and we need to add corresponding instructions;
When the subscript is out of bounds, we can catch an out_ of_ The exception of range is defined in the < stdexcpt > header file. We also need to add the include instruction;
Note that "using namespace std;" needs to be added after these #include instructions, otherwise compilation errors will occur
#include <stdio.h> #include <random> #include <stdexcept> #include <vector> using namespace std; #define LEN 10 int main(int argc, char** argv) { srand(time(NULL)); vector<int> vec; int i = 0; for (; i < LEN; ++i) { vec.push_back(rand() % 50); } while (1 == scanf("%d", &i)) { try { printf("p[%d]= %d\n", i, vec.at(i)); } catch(out_of_range e) { printf("Wrong index!\n"); } } return scanf("%*s"); }
3. Uninitialized error
Sometimes we don't initialize variables, resulting in strange results
#include <stdio.h> #define LEN 10 int main(int argc, char** argv) { int* p = new int[LEN]; int i = LEN; for (; --i; p[i] = i); // Wrong code; for (i = 0; i < LEN; ++i) { printf("%d, ", p[i]); } delete[] p; return scanf("%*s"); }
Let's look at the first for loop. Its condition is -- i, which is equivalent to -- i= 0
When i = 0, the cycle ends; We only initialize p[1] to p[9], but not p[0];
Therefore, the first number of the output of this program is generally very strange
The correct way is to change -- i to -- i > = 0
Of course, we can also change int* p = new int[LEN] to int p[LEN] = {};
Then delete[] p;
When defining an array, if you use the new operation, it belongs to dynamic memory allocation. After using it, you need to use delete [] to free memory; In this case, the value of the array element may not be initialized
If curly braces are used to initialize the array, it belongs to static memory allocation, and there is no need to write delete
When the brace content is empty, all numeric elements are initialized to 0, and other types of elements are the default initial values
Of course, we can initialize directly in braces, for example:
int ar[6] = { 1, 5, 2 };
For the first three elements, we directly define the initial value, and for the following elements, it will be set to 0
The above expression is equivalent to:
int ar[6] = { 1, 5, 2, 0, 0, 0 };
4. Type conversion error
Let's take an example:
#include <iostream> #include <string> using namespace std; int main(int argc, char** argv) { string str = "AB"; int num = 6; str = (num + '0') + str; // Error here! printf("%s\n", str.c_str()); num = 3; str += (num + '0'); cout << str << endl; return scanf("%*s"); }
In str = (Num +'0 ') + STR, there is a compilation error, which involves the problem of type conversion;
Because num is an integer and '0' is a character. If both exist in an expression, the latter will also be converted to an integer,
Therefore, the result of (Num +'0 ') is int type, and the + operator is not supported between it and string type, so an error is reported
The correct way to write is to explicitly convert the type:
str = (char)(num + '0') + str;
The following STR + = (Num +'0 ') does not need to write (char), and the compilation and operation are normal,
This is because the + = operator of string will interpret the following int as the ASCII code of the character
There are two types of type conversion, explicit conversion and implicit conversion
Explicit conversion is to add a pair of parentheses before the variable to be converted, and write the type in the parentheses, for example:
int n = 10; float a = (float)n;
When we assign a value to a, we use the value of int variable n. in this case, we need to convert it to float
For implicit conversion, nothing is added and the compiler is allowed to automatically convert, for example:
int n = 10; float a = n;
In this case, the compiler will automatically convert the n in line 2 to float
However, I suggest you use explicit conversion instead of implicit conversion, because the latter is prone to error
Today, I will introduce it here and continue to update it in the future^_^