Practical debugging skills that novices must master (vs2019)

Directory

1. What is a bug?

2. What is debugging?

2.1. What is debugging

2.2. Basic steps of debugging

2.3. Introduction to Debug and Release

3. Introduction to debugging in Windows environment

3.1. Preparation for debugging environment

3.2, learn shortcut keys

3.3. View the current information of the program during debugging

3.3.1. Check the value of the temporary variable

3.3.2. View memory information

3.3.3, check the call stack

3.3.4. View compilation information

3.3.5. View register information

4. Example of debugging

6. How to write good (easy to debug) code

6.1. Excellent code

6.2 Demonstration

6.3, the role of const

How to use const and understand the difference between const int* and int *const

7. Common errors in programming

7.1. Compilation errors

7.2. Link error

7.3. Runtime errors


1. What is a bug?

The English interpretation of BUG is “worm”. Now people refer to some undiscovered defects or problems hidden in computer systems or programs as bugs (loopholes). The first program BUG in human history is related to bugs.

In 1937, a young American guy found IBM and asked for 2 million yuan to make a computer. The first finished product was named “Mark 1”, and the code was written by a young girl named Reese Hope. One day, he failed when debugging the program. After a while of twists and turns, he found that a moth was burned in the middle of the two relays, causing a short circuit. So the program failures are collectively referred to as “bugs BUG”. Since then, the worm has been immortalized forever and is preserved forever in the National Museum of American History in Washington.

2. What is debugging?

2.1, What is debugging

Generally refers to the code you wrote. After compiling in Debug mode, the compiler inserts debugging information into your code. You can run the program step by step and view the intermediate results. It is applicable to your program running incorrectly. You need to check the intermediate process to make sure when the source of the problem.

2.2, the basic steps of debugging

  • detect the presence of programming errors
  • Locate errors by isolating, eliminating, etc.
  • determine the cause of the error
  • Propose a solution to correct the error
  • Correct program errors and retest

Introduction to 2.3, Debug and Release

  • Debug is usually called the debug version, which contains debugging information and does not make any optimizations, which is convenient for programmers to debug programs
  • Release is called a release version, which is often optimized to make the program optimal in code size and running speed, so that users can use it well
  • The configuration can be selected here in the compiler

3. Introduction to debugging in Windows environment

3.1, preparation for debugging environment

Select the debug option in the environment to make the code debug normally

3.2, learn shortcut keys

The following are commonly used shortcut keys for debugging:

F5: Start debugging, often used to jump directly to the next breakpoint (if there is no breakpoint, the entire program will be run)
F9: Create breakpoints and cancel breakpoints. The important role of breakpoints can be set anywhere in the program. In this way, the program can be stopped at any desired position, and then executed step by step
F10: Process by process, usually used to process a process, a process can be a function call, or a statement
F11: Statement by statement, that is, execute a statement each time, but this shortcut key can make the execution logic enter the function, which is the most commonly used
Ctrl + F5: Start execution without debugging, if you want the program to run directly without debugging, you can use it directly

3.3. View the current information of the program during debugging

Note: All of the following are operable after debugging starts

3.3.1. View the value of a temporary variable

All four monitoring windows can be used, you only need to enter legal monitoring content in the monitoring name

3.3.2. View memory information

Same as the monitoring window, all four ports can be used

Enter the address you want to query in the address, and you can choose it yourself in the column

After selecting, press Enter to view

3.3.3. Check the call stack

3.3.4, view assembly information

3.3.5. View register information

4. Example of debugging

#include <stdio.h>
int main()
{
int i = 0;
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };

for (i = 0; i <= 12; i ++ )
{
arr[i] = 0;
printf("hehe\\
");
}
return 0;
}

Debug as follows

6. How to write good (easy to debug) code

6.1, excellent code

Good code should have: 1. The code works properly

2. Few bugs

3. High efficiency

4. High readability

5. High maintainability

6. Comments are clear

7. Complete documentation

Our common coding skills are: 1. Use assert

2. Try to use const

3. Develop a good coding style

4. Add necessary comments

5. Avoid Coding Pitfalls

6.2, demonstration

For the coding skills we mentioned above, we will implement them in the following example

Here we simulate the library function: strcpy

First of all, let’s take a look at the parameters and return value types of this function

The return value type is char*, and the parameters are all char*. Const will be discussed later. Next, we will implement it. First, write the main function as follows:

//int main()
//{
// char arr1[] = "hello bit";
// char arr2[20] = "xxxxxxxxxxxxxx";
// printf("%s\\
", my_strcpy(arr2, arr1));
// return 0;
//}

This is how we write when we don’t know to use const

//char* my_strcpy(char* dest, char * src)
//{
// char* ret = dest;//Because the subsequent ++ operation will change the address pointed to by dest, so here the first address is stored in ret in advance
// while (*dest = *src)
// {
// dest++;
// src++;
// }
// return ret;//return ret, which is the initial dest, for subsequent printf printing
//}

And this code can actually be optimized, as follows

//char* my_strcpy(char* dest, const char * src)
//{
// char* ret = dest
// while (*dest + + = *src + + ) // optimized
// ;//empty statement
// return ret;
//}

But the user doesn’t know how we should give the parameter, if the user accidentally gives a null pointer, for example, the following

We found that the code did not report an error, and we went on, but is this what we need? Obviously not, at this time we need to use the assert (assertion) mentioned above, and use it with the header file #include

Assertion (assertion) is a kind of first-order logic in the program (such as: a logical judgment formula that the result is true or false), the purpose is to express and verify the expected result of the software developer – when When the program executes to the position of the assertion, the corresponding assertion should be true. If the assertion is not true, the program will abort execution and give an error message.

Use as follows

?
char* my_strcpy(char* dest, const char * src)
{
// // assert
assert(dest != NULL);
assert(src != NULL);
char* ret = dest;
while (*dest + + = *src + + ) // optimized
;//empty statement
return ret;
}

?

Let’s test it to see the effect

We found that it does not do nothing, but reports to you where an error occurs in your code. Here we show that an error occurred on line 8, and our line 8 received a null pointer, so the program will stop executing and gives an error message.

When we got this done, we had a problem again. A careless little partner reversed *dest + + = *src + + and wrote *src + + =*dest + + when implementing it. At this time, we It is found that the program is running normally, but the result given is wrong. How should we solve it? At this time, we need to use the const we will talk about next.

6.3, the role of const

const is a C language (ANSI C) keyword that plays a pivotal role. It restricts a variable that is not allowed to be changed, resulting in a static effect. Using const can improve the security and reliability of the program to a certain extent. In addition, when viewing other people’s code, a clear understanding of the role played by const is also helpful to understand the other party’s program.

The data type modified by const refers to the constant type, and the value of the variable or object of the constant type cannot be updated.

main effect
1. You can define const constants, which are immutable
2. It is convenient for type checking, so that the compiler has a better understanding of the processing content and eliminates some hidden dangers. For example: void f(const int i) { …} The compiler will know that i is a constant and cannot be modified;
3. It can protect the modified things, prevent accidental modification, and enhance the robustness of the program.
4. Save time and improve efficiency, the compiler usually does not allocate storage space for ordinary const constants, but saves them in the symbol table, which makes it a constant during compilation, without the operation of storing and reading memory, making It is also very efficient.

Let’s take a quick look

We found that when modifying n, the compiler reported an error because n cannot be updated

How to use const and understand the difference between const int* and int *const

Explain with a simple code example

#include <stdio.h>

void test1()
{
int n = 10;
int m = 20;
int *p = &n;
*p = 20;
p = &m;
}
void test2()
{
int n = 10;
int m = 20;
const int* p = &n;
*p = 20;
p = &m;
}
void test3()
{
int n = 10;
int m = 20;
int *const p = &n;
*p = 20;
p = &m;
}

int main()
{
//Test without cosnt
test1();
// test const on the left of *
test2();
// test const on the right of *
test3();
return 0;
}

We tested and found

The test1() function can run normally, but test2() and test3() cannot.
The function of const int* p = &n; in test2() is to make the pointer unable to change the value pointing to the current address, that is to say, n is equal to 10 at this time, and the value of n cannot be changed through the pointer p. *p=20; At this time, this sentence will report an error.
The function of const int *const p = &n; in test3() is to prevent the pointer from changing the address currently pointed to. That is to say, at this time, p points to the address of n, and cannot be changed to point to the address of m. p = & amp;m; This sentence will report an error

Summarized as follows

/const modify the pointer
129 when const put When on the left side of *, the content pointed to by the pointer is restricted, and the content pointed to by the pointer cannot be changed through the pointer variable, but the pointer variable itself can be changed
130 When const is placed on the right side of *, the restriction is the pointer variable itself, the pointer variable itself cannot be changed, but the content pointed to by the pointer can be changed through the pointer of

The complete implementation of the my_strcpy() function is as follows

//char* my_strcpy(char* dest, const char * src)
//{
// char* ret = dest;
// // assert
// assert(dest != NULL);
// assert(src != NULL);
//
// while (*dest + + = *src + + )
// ;//empty statement
//
// return ret;
//}

7. Common mistakes in programming

7.1, compilation error

Directly see the error message (double-click), and solve the problem. Or it can be done with experience. relatively simple

Double-click an error to jump to the problem line

Looking at the error message, the protagonist is to find the identifier in the error message in the code, and then locate the problem. The generic identifier does not exist or is misspelled

As the above spelling error, we found after compiling

7.3, runtime error

With the help of debugging, it is the most difficult to locate the problem step by step. Need to accumulate experience slowly.

It’s not easy to make, one-click three links! ! work hard together! ! !