C language savior side story (Windows practical debugging skills)

Note: The debugging tool for the Linux development environment is gdb, which will be introduced later in the blog.

content

An important technique for programmers to master is to learn to debug

1.1 What is debugging? How important is it?

1.2 Basic steps of commissioning

2.1 Debug and Release

2.2 The difference between the Debug and Release versions of the following programs

2.3 How to use shortcut keys

2.4 Example question: I want to know whether 153 is an exponent. Are you stupid and keep pressing F10, how long does it take when i=100000?

 3.1 Identify code problems by debugging

Implementation code: ask for 1! +2! +3! ...+ n! ; overflow is not considered. (there is an error in the code below)

3.2 How to write good (easy to debug) code 

3.3 Simulate the library function: strcpy (string copy)

The my_strcpy function is designed to return the value type char* to achieve chained access to the function

4.1 Const Exercise Explanation

5.1 Common mistakes in programming

5.2 Compilation errors are syntax errors

5.3 Chaining errors 

5.4 Runtime Errors - Errors Solved with Debugging (Example of Factorial)


An important technique for programmers to master is to learn to debug

Some women are like Windows, although very good, but the security risks are too great. 
Some women are like UNIX. She is very good, but not everyone can play. 
Some women are as beautiful as C#, but can't do housework. 
Some women are like C++, she will silently do a lot of things for you. 
Some women are like JAVA, she will serve you everywhere with just a little pay. 
Some women are like JAVA scripts, although they are careful with her, they still have no results in the end. 
Some women are like compilation, although it is troublesome, but sometimes you have to ask for it. 
Some women are like SQL, and she will be a great help in your development. 
Love is an endless cycle, once it is executed, it falls into it. 
Falling in love with someone is a memory leak, and you can never release it. 
When you truly fall in love with someone, it is constant and will never change. 
Girlfriend is a private variable that only my class can call. 
Lover is the pointer, you must pay attention when using it, otherwise it will bring huge disaster.


1.1 What is debugging? How important is it?

There must be traces of everything that happens. If you have a clear conscience, you don’t need to cover up and there will be no signs. If you have a conscience, you must cover up, and there must be signs. The more signs, the easier it is to follow the vine And above, this is the way of reasoning. Going down this path is a crime, going upstream is the truth.

 Debugging (English: Debugging / Debug), also known as debugging, is a process of finding and reducing program errors in computer programs or electronic instruments.


1.2 Basic steps of commissioning

Find the existence of program errors

Locate errors by isolating, eliminating, etc.

Determine the cause of the error

propose solutions to correct mistakes

Correct program errors and retest


2.1 Debug and Release

Debug is often referred to as the debug version, which contains debugging information and does not make any optimizations, making it easier for programmers to debug programs.

Release is called a release version, and it is often optimized in various ways to make the program optimal in code size and running speed, so that users can use it well. (cannot debug)

2.2 The difference between the Debug and Release versions of the following programs

#include <stdio.h>
int main()
{
    int i = 0;
    int arr[10] = {0};
    for(i=0; i<=12; i++)
   {
        arr[i] = 0;
        printf("hehe\n");
   }
    return 0;
}

In the debug version, the program loops infinitely; in the release version, the program can execute

The reason is that the order in which variables are created in memory has changed, which affects the result of program execution.

The result of the code running: the high probability is an infinite loop

First of all, arr has only 10 elements, but i loops to 12 times, and arr[10] has been accessed out of bounds. First, i and arr are local variables, first create i, and then create arr, and because local variables are placed on the stack On the area, the usage habit of the stack area is to use the high address first, and then use the low address

If i is initialized first, put it on the top, and arr is an array, but the growth address of the subscript of the array grows from low to high. If the array is out of bounds, it may cross the boundary to the address of i once, and put the address of i and arr The address of the array is changed to 0, and the for loop restarts the calculation. Why is the result likely to be an infinite loop, because you don't know how many bytes are between the addresses of the arr array and i, but if the arr array is out of bounds to access the i will cause an infinite loop

Putting arr and i in reverse is also because of the usage habits of the stack area. If i is post-initialized, i is the low address space, so arr out-of-bounds access will never access the address of i, so the program will crash after printing.

The amount of empty space in the middle is a matter of the compiler's own writing method. For example, if you go to other platforms, the empty space may be different, so why is there an infinite loop and no error is reported? Because the program has been running, the for loop has not stopped. Although arr is accessed out of bounds, the program must be executed before it can report an error, and one thing must be completed.


	int main()
	{
		int i = 0;
		int arr[10] = {1,2,3,4,5,6,7,8,9,10};
		printf("%p\n", &i);
		printf("%p\n", &arr[9]);
		}
 

可以佐证,栈区空间使用习惯先使用高地址,再使用低地址

 


2.3 How to use shortcut keys

1.F5 to start debugging

How to use: Press F5 directly to end the program, it cannot be used alone, it needs to be used with F9 (breakpoint)

(Press F5 multiple times, it will stop at the original logical breakpoint, for example, the loop changes from one time to two times, and stops at the next loop breakpoint), some people will find that pressing F5 does not respond, then you need to add Fn+F5 or Fn+F10

2.Ctrl + F5 do not debug, execute the code directly

3.F9 set/cancel breakpoint

How to use: code execution, press F5, and stop only when the breakpoint F9 is encountered

4. Ctrl + F to find keywords

5. Ctrl + K+C to add a comment (used with select all) Ctrl + K+U to uncomment

6. Copy in C language does not need to select copy, just press Ctrl+V on the line that needs to be copied to copy

In addition, there are more shortcut keys, blog added below

Commonly used shortcut keys in VS - MrLisky's blog - CSDN blog - VS shortcut keys

Some students found that when I opened Debug -> Window, I didn't find the monitoring. Why?

This is because many windows in monitoring are displayed only when debugging is started. Monitoring is used to cooperate with code to check errors, and more practice is required.


2.4 Example question: I want to know whether 153 is an exponent. Are you stupid and keep pressing F10, how long does it take when i=100000?


int main()
{
	int i = 0;
	for (i = 0; i <= 100000; i++)
	{
		int tmp = i;
		int n = 1;
		//第一步判断是几位数
		while (tmp / 10)
		{
			n++;
			tmp = tmp / 10;
		}
		//计算每一位次方和
		tmp = i;
		int sum = 0;
		while (tmp)
		{
			sum += pow(tmp % 10, n);
			tmp = tmp / 10;
		}
		//3.判断
		if (i == sum)
		{
			printf("%d ", i);
		}
	}
	return 0;
}

We can use F5 to cooperate with F9, right-click at the F9 breakpoint -> condition (conditional breakpoint), enter i==153 (conditional setting), press F5 at this time, you will find that i skips 152 bits and goes directly to 153


2.5 F10 (step by step, when encountering a function, it will not enter the function, and directly execute the complete function content)

  F11 (statement by statement, when encountering a function, it will enter the function and execute every detail of the code)

int Add(int a, int b)
{
	return a + b;
}

int main()
{
	int a = 1;
	int b = 2;
	int ret = Add(a,b);
	printf("%d", ret);
	return 0;
}

F10 until you are at the function Add, press F11 to enter the function, use it with the monitoring window, in addition to monitoring and automatic monitoring (not recommended), automatic monitoring helps you to release all the variables, it is easy to observe the specified number Error, we just need to observe the number we want in the monitor

memory monitoring


Call stack, when the function call logic is complex, you can view the call logic of the stack

void test2()
{
	printf("hehe\n");
}
void test1()
{
	test2();
}
void test()
{
	test1();
}
int main()
{
	test();
	return 0;
}

 3.1 Identify code problems by debugging

Implementation code: ask for 1! +2! +3! ...+ n! ; overflow is not considered. (there is an error in the code below)

int main()
{
 int sum = 0;//保存最终结果
 int n = 0;
 int ret = 1;//保存n的阶乘
 scanf("%d", &n);
 for(int i=1; i<=n; i++)
 {

 for(int j=1; j<=i; j++)//n的阶乘
 {
 ret *= j;
 }
 sum += ret;
 }
 printf("%d\n", sum);
 return 0;
}


//1!=1
//2!=2
//3!=6
//9
We want 3! , Enter 3 but find that the result is 15, there must be a problem with the code, so we press F10 to start debugging, and then enter the variable we want to observe in the monitoring

The first execution,

There is no problem with the code, 1! is 1

 

The second execution, 2! It is 2, but we continue to execute down, but find that the ret value is 2. You must know that the role of ret is the role of 1*2*...*n, the ret value has changed, and the result is naturally wrong.

int main()
{
 int sum = 0;//保存最终结果
 int n = 0;
 int ret = 1;//保存n的阶乘
 scanf("%d", &n);
 for(int i=1; i<=n; i++)
 {
   ret = 1;
 for(int j=1; j<=i; j++)//n的阶乘
 {
 ret *= j;
 }
 sum += ret;
 }
 printf("%d\n", sum);
 return 0;
}

3.2 How to write good (easy to debug) code 

1. The code runs normally 2. There are few bugs 3. High efficiency 4. High readability 5. High maintainability 6. Clear comments 7. Complete documentation

Common coding techniques:

1. Using assert

2. Try to use const

3. Develop good coding style

4. Add necessary comments

5. Avoid coding pitfalls.

3.3 Simulate the library function: strcpy (string copy)

Copy the content pointed to by the original pointer to the space pointed to by the destination space pointer, and also copy \0 to the past

 

Out of 10 points, this code gives 5 points and fails, although he can also complete the string copy we want to achieve

void my_strcpy(char* dest, char* src)//将src空间处的字符拷贝到目标空间dest
{
	while (*src != '\0')
	{
		*dest = *src;
		dest++;
		src++;
	}
	*dest = *src;//再把\0拿下来
}

int main()
{
	char arr1[] = "hello bit";
	char arr2[20] = "xxxxxxxxxxx";
	my_strcpy(arr2,arr1);

	return 0;
}

How to improve? First, the string copy is done twice, can we optimize

Can be changed to post ++

void my_strcpy(char* dest, char* src)
{
	while (*src != '\0')
	{
		*dest++ = *src++;
	}
	*dest = *src;
}
assert is used to assert. When the two pointers we pass are NULL, and the application is performed without assertion, we will access the memory illegally, and the code is at risk.
The above code is still not simplified enough, can we combine the two sentences dest = src,
#include <assert.h>

void my_strcpy(char* dest, char* src)
{
	//assert(dest != NULL);//断言
	//assert(src != NULL);//断言

	assert(dest && src);//优化断言,一个为假(NULL)便报错

	while (*dest++ = *src++)//先执行src,src指向hello bit,由于++是后置,先使用再++
                            //h被*dest内容复制,表达式结果是h的ASCII码值
                            // \0的ASCII码值为0,先执行完\0 = x,表达式不成立结束循环
	{
		;
	}
}

Then we look at the introduction of the official version of strcpy

char *strcpy( char *strDestination, const char *strSource );

The my_strcpy function is designed to return the value type char* to achieve chained access to the function

It is also necessary to add const, so that the variables at the src target space cannot be modified (become constant variables), so as to avoid code errors

Perfect function design!

char* my_strcpy(char* dest, const char* src)
{
	assert(dest && src);//断言
	char* ret = dest;
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}

int main()
{
	char arr1[] = "hello bit";
	char arr2[20] = "xxxxxxxxxxx";
	char* p = NULL;

	printf("%s\n", my_strcpy(arr2, arr1));

	return 0;
}

4.1 Const Exercise Explanation

Const is to make our code more robust, but how do we use const to restrict exactly what code we want?

int main()
{
	int num = 10;
	num = 20;//第一种方法改num变量值
	int* p = &num;
	*p = 100;//指针方法改变num变量值

	return 0;
}

What happens if you add const?

int main()
{
    const int num =0;//常变量,不可被修改
    num = 20;  //编译器不通过
    int * p =&num;
    *p = 20;//成功改掉,编译器通过,证明我们可以使用指针来去改被修饰的常变量
    printf("%d\n", num);//20 这种操作破坏了const,本意不改却被投机取巧改掉了
	return 0;
}

Locked the door and prevented you from entering through the door, but you smashed the window and jumped in. Although you entered, it was illegal

int main()
{
    const int * p =&num;
    *p = 20;//X 窗户也给你封死
    int * const p =&num;
    p = 20 ; //X  门封死
    const int * const p =&num;//X 窗户, 门封死也给你封死
	return 0;
}

const can modify pointers:
    const is placed on the left side of * (const int* p;)
    const modifies *p, which means that the object pointed to by p cannot be changed by p, but the address in the p variable can be changed.
    const is placed in * The right side of (int* const p;)
    const modifies p, which means that the content of p cannot be changed, but the object pointed to by p can be changed through p


 

5.1 Common mistakes in programming

5.2 Compilation errors are syntax errors

int main()
{
   return 0     //漏掉了;  在编译过程中报错,没有运行起来
}

 Solution: Look directly at the error message (double-click) to solve the problem. Or you can do it with experience. Relatively simple.

5.3 Chaining errors 

//没有引头文件
//int Add(int x, int y)//或者没有定义Add函数
//{
	//return x + y;
//}

int main()
{
	int a = 10;
	int b = 20;
	
	int c = add(a, b);//函数名写错了
	
	printf("%d\n", c);

	return 0;
}

 

Solution: Look at the error message, mainly find the identifier in the error message in the code, and then locate the problem. Usually the identifier name does not exist or is misspelled.

5.4 Runtime Errors - Errors Solved with Debugging (Example of Factorial)


The basic knowledge of C language is over!

Guess you like

Origin blog.csdn.net/weixin_63543274/article/details/123756664