Common errors in C + + programs_ one

Keywords: C++

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^_^

Posted by spivey on Sat, 27 Nov 2021 15:00:58 -0800