当前位置:网站首页>Make the code elegant (learn debugging + code style)

Make the code elegant (learn debugging + code style)

2022-06-22 16:32:00 Xin Xiangrong

 Insert picture description here
Blog home page : Xin Xiangrong
Series column :【 from 0 To 1,C Language learning 】
A short sentence : If you are in full bloom , Butterflies come !
Blog description : Do what you can , Write every blog , Help yourself familiarize yourself with what you have learned , I also hope these contents can help some partners on the way of learning , If errors and deficiencies are found in the article , Also hope to leave a message in the comment area , We communicate progress together !

Preface

This article describes how to write good code , Starting from the code style and practical debugging skills , Although the style of the code will not affect the operation of the program , But good code style can make our code logic clearer , And it is very important for a programmer to learn how to debug programs , The code we write should be easy to debug , Good code can avoid a lot of unnecessary trouble , Save us time !

One . Practical debugging skills

1. understand bug

Program error , In English Bug、 Bedbug , Is refers to in the software operation because the program itself has the error and the function is not normal 、 crash 、 Data loss 、 Abnormal interruptions . Early computers were very large , Some bugs may get into the machine Inside , Cause computer failure . The first in history “Bug” , It's really because a moth accidentally walked into a computer and caused a failure ], therefore Bug Bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug bug .

img

We are learning to encode , At the beginning of school , Because I am not familiar with grammar , There may be syntax errors between the lines of the code, which will cause the code program to fail to run ; And the code we write will not report errors , But the result of the code is different from what we thought , Can't get the right result … These various reasons lead to problems in the code program 、 Mistakes are related to us bug 了 .

2. Understanding and debugging

Everything that happened must have a trace to follow , If you have a clear conscience , There is no need to cover up and there is no sign , If you have a guilty conscience , It is necessary to cover up , Then there must be signs , The more signs, the easier it is to follow the vine , This is the way of reasoning .

Following this path down the river is a crime , Go against the current , It's the truth .

A good programmer is a good detective , Every debugging is a process of trying to solve the case .

2.1 What is debugging

** debugging (** English :Debugging / Debug), Also known as debugging , It is a process of finding and reducing program errors in computer programs or electronic instruments and equipment ; It is actually a process of correcting errors in the code !

For repair bug...

Write code …

img

Check the problems …

img

If you are in the state of the picture but not , Learn how to debug programs correctly , Reject superstitious debugging !!!

2.2 The basic steps of debugging

  • Find the existence of program errors
  • To isolate 、 Eliminate and so on
  • Determine the cause of the error Propose solutions to correct errors
  • Correct procedural errors , To test

2.3 Debug and Release Introduction to .

  1. Debug Usually called debug version , It contains debugging information , And without any optimization , It's easy for programmers to debug programs .
  2. Release It's called a release , It's often optimized , Make the program in code size and running speed are optimal Of , So that users can use it well .

See how the following code works in two environments !

#include<stdio.h>
int main()
{
    
	char* p = "hello world";
	printf("%s\n", p);

	return 0;
}

The above code is in Debug The results of the environment show :

img

The above code is in Release The results of the environment show :

img

Debug and Release Disassembly shows comparison :

img

So we say debugging is Debug Version of the environment , A process of finding potential problems in code ; And in the Release In the environment, we can clearly see the simplicity of the optimized code execution , Some steps are omitted , Debugging is not supported !

Here's another look Release What optimizations have the compiler done in mode ?

Look at the following code :

#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\n");
	}
    
	return 0;
}

If it is debug Mode to compile , The result of the program is an endless loop .

If it is release Mode to compile , There is no dead cycle in the program .

img

So what's the difference between them ? It's because of optimization .

3. Learn to debug (windows Environmental Science )

3.1 Preparation of debugging environment

img

Only in Debug Environment , To debug the code normally !

3.2 Familiarize yourself with the necessary shortcuts

img

F5

Start debugging , Often used to jump directly to the next breakpoint .

F9

Create breakpoints and cancel breakpoints The important role of breakpoints , Breakpoints can be set anywhere in the program . In this way, the program can stop executing at the desired position , Then carry it out step by step .

F10

Process by process , Usually used to deal with a process , A procedure can be a function call , Or a statement .

F11

Sentence by sentence , Is to execute one statement at a time , But this shortcut can make our execution logic enter the function ( This is the most frequently-used ).

CTRL + F5

Start execution without debugging , If you want the program to run directly without debugging, you can use it directly .

commonly F5 And F9 In combination with , When we write long code , Use F10/F11 Step by step debugging can be a waste of time ; and F5 and F9 It will be very convenient , We put a breakpoint where we want the program to stop , Press F5 You can skip the previous code , Make the program run directly to the breakpoint .
When you press... Again F10 Debugging will run to the next logical breakpoint !

3.3 Check the current information of the program during debugging

3.3.1 View the value of the temporary variable

After debugging starts , The value used to observe the variable .

img

The most commonly used one here is the monitor window , We can input any legal variable to view its value ; While the automatic window and local window follow the debugging process , The content monitored is dynamically changing , Can't synchronize with what we want , Very inconvenient .

3.3.2 View memory information

img

3.3.3 call Stack

img

Through the call stack , Can clearly respond to the call function and the location of the current call. .

3.3.4 View assembly information

After debugging starts , There are two ways to go to assembly :

The first way : Right click mouse , choice 【 Go to disassembly 】:

img

The second way :

img

You can switch to assembly code .

3.3.5 Check register information

img

If you want to know more about assembly , You can take a look at my other blog About function stack frame .

It is suggested to do more , Try debugging to solve the problem :

  • Be sure to master debugging skills .
  • Beginners may 80% Time to write code ,20% Time to debug . But a programmer may 20% Time to write Program , however 80% Time to debug .
  • Here are some simple and basic debugging . There may be very complex debugging scenarios in the future : Debugging of multithreaded programs, etc , We need to constantly try to solve .
  • Use more shortcut keys , Improve efficiency .

5. Debugging example

#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\n");
	}

	return 0;
}

The code described above is in vs Of Debug-x86 In the environment , The running result is an endless loop !

So what is the cause of the dead cycle ?

If we just stare at the code for problems , Can you see which step is wrong ?

So here we need to find out the problem through debugging !

We F10 Go step by step to debug , Open the monitoring window to observe the variables , During debugging, it can be found that the elements within the array range are normally assigned as 0;

img

When the program is in the next step of debugging ,i The value of will be added as 10, At this point, the array is accessed beyond the bounds , At this time arr[10] Whether it will be assigned as 0, Consider whether the question is here , Then debug , You can find the cross-border arr[10] and arr[11] Normal assignment ;

img

Continue debugging , here i= 12, Observe arr[12] Or assigned to 0, But in this step of debugging , Observation variables i The value of is found in arr[12] To be an assignment 0 At the same time i The value of also becomes 0;

img

At this point, we found the cause of the program loop through debugging , Why will arr[12] The assignment is 0 At the same time i The value of also becomes 0, We speculate that the possible cause is arr[12] and i It takes up the same memory space ! Compare the memory addresses of the two and find that they are indeed the same !

img Analyze why the two memory addresses are the same !

Memory space in the computer , It is divided into stack area 、 Heap area and static area ;

For local data, the memory is allocated in the stack area !

img

6. Common programming errors

  1. Compiler error ( Grammar mistakes )
  • Look directly at the error message ( double-click ), solve the problem . Or you can do it with experience . Relatively simple .
  1. Linked error
  • Look at the error message , Mainly find the identifier in the error message in the code , Then locate the problem . Generally, the identifier name is not There are or spelling mistakes .
  1. Runtime error
  • With the help of debugging , Gradually locate the problem . It's the hardest thing to do .

Two . How to write good code

Good code has the following characteristics :

  • The code is working properly
  • bug Very few
  • Efficient
  • High readability
  • High maintainability
  • The notes are clear
  • The documentation is complete

So how to write good code , There are two aspects here :

  1. Good code style
  2. Easy to debug code

( One ) Learn to use good code style

1. File structure

Every C++/C The program is usually divided into two files . A file is used to save the declaration of the program (declaration), It's called a header file . Another file is used to save the implementation of the program (implementation), It's called definition (definition) file .

C++/C The header file of the program is “.h” For the suffix ,C The definition file of the program is as follows “.c” For the suffix ,C++ Program The definition file of is usually in the form of “.cpp” For the suffix ( There are also systems to “.cc” or “.cxx” For the suffix ).

1.1 The structure of the header file

The header file consists of two parts :

(1) Pretreatment block .

(2) Function and class structure declaration, etc .

【 The rules 1-1-1】 To prevent the header file from being repeatedly referenced , Should use ifndef/define/endif Structure produces preprocessing blocks .

【 The rules 1-1-2】 use #include Format to reference the header file of the standard library ( Compiler will Search from the standard library directory ).

【 The rules 1-2-3】 use #include “filename.h” Format to refer to the header file of the nonstandard library ( Compiler will Search from the user's working directory ).

【 Suggest 1-1-1】 Only... Is stored in the header file “ Statement ” Instead of storing “ Definition ”

【 Suggest 1-1-2】 Global variables are not recommended , Try not to appear in the header file extern int value this Class declaration .

img

1.2 Define the structure of the file

The definition file also has two parts :
(1) References to some header files .

(2) Program implementation body ( Including data and code ).

img

1.3 Directory structure

If a software has a large number of header files ( If there are more than ten ), In general, header files and definition files should be divided into Don't save in different directories , To facilitate maintenance .

For example, you can save the header file in include Catalog , Save the definition file in source Catalog ( It can be multi-level Catalog ).

If some header files are private , It's not directly referenced by the user's program , There's no need to make it public “ The sound bright ”. To enhance information hiding , These private header files can be stored in the same directory as the definition files .

2. The layout of the program

Although the layout does not affect the function of the program , But the format of the program is clear 、 beautiful , yes An important component of program style .

The layout of a program can be compared to “ calligraphy ”.

2.1 Blank line

Blank lines serve to separate program paragraphs . It's nice and empty ( But not too much ) Will make the layout of the program more Clear .

【 The rules 2-1-1】 After each class declaration 、 Every function definition ends with a blank line .

【 The rules 2-1-2】 In a function body , There is no blank line between the closely related sentences in the logic , Other places should Separate with blank lines .

img

2.2 Lines of code

【 The rules 2-2-1】 One line of code does one thing , If only one variable is defined , Or just write a statement . such The code is easy to read , And it's easy to write notes .

【 The rules 2-2-2】if、for、while、do Wait for the sentence to take up a line , The execution statement must not be followed by . Regardless of Execute as many statements as you want {}. This will prevent mistakes in writing .

【 Suggest 2-2-1】 Try to initialize a variable while defining it ( Nearby principle )

img

2.3 Space in the line of code

【 The rules 2-3-1】 Leave a space after the keyword . like const、virtual、inline、case Leave at least one space after the keyword , Otherwise, we can't discriminate keywords . like if、for、while Should be left after keywords such as A space followed by an open parenthesis ‘(’, To highlight keywords .

【 The rules 2-3-2】 Do not leave spaces after function names , Follow the left bracket ‘(’, To distinguish from keywords .

【 The rules 2-3-3】‘(’ Follow closely ,‘)’、‘,’、‘;’ Keep up with , There is no space at the end of the line . 【 The rules 2-3-4】‘,’ Leave a space after , Such as Function(x, y, z). If ‘;’ Not the end of a line Symbol , Leave a space after , Such as for (initialization; condition; update).

【 The rules 2-3-5】 Assignment operator 、 Comparison operator 、 arithmetic operator 、 Logical operators 、 Bitfield operators , Such as “=”、“+=” “>=”、“<=”、“+”、“*”、“%”、“&&”、“||”、“<<”,“^” The binary operator should be preceded by a space .

【 The rules 2-3-6】 A unary operator is like “!”、“~”、“++”、“–”、“&”( Address operators ) Wait before and after Add space .

【 The rules 2-3-7】 like “[]”、“.”、“->” There is no space before and after such operators .

【 Suggest 2-3-1】 For long expressions for Statement and if sentence , For the sake of compactness, you can go to Drop some spaces , Such as for (i=0; i<10; i++) and if ((a<=b) && (c<=d))

img

2.4 alignment

【 The rules 2-4-1】 The program separator ‘{’ and ‘}’ Should have a single row and be in the same column , At the same time with reference to Their statements are left aligned .

【 The rules 2-4-2】{ } The code blocks inside are in ‘{’ Left aligned on the right .

img

2.5 Long line split

【 The rules 2-5-1】 The maximum length of code line should be controlled in 70 to 80 Within characters . Don't be too long , no The eyes can't see , It's not easy to print .

【 The rules 2-5-2】 Long expressions are split into new lines at low priority operators , Put the operator at the beginning of the new line ( With Then highlight the operator ). The split new line should be indented appropriately , Make the typesetting neat , Statements are readable .

img

3. Naming rules

3.1 Common rules

【 The rules 3-1-1】 The identifier should be intuitive and readable , It is expected that the text will know the meaning , It doesn't have to be “ decode ”; It is better to use English words or a combination of them , Easy to remember and read . Never use Chinese pinyin to name .

【 The rules 3-1-2】 Do not use similar case sensitive identifiers in your program .

【 The rules 3-1-3】 Do not have local variables and global variables with identical identifiers in the program , Although both Different scopes without syntax errors , But it's misleading .

【 The rules 3-1-4】 The name of the variable should use “ Noun ” perhaps “ Adjective + Noun "; Global functions should be named with “ Verb ” perhaps “ Verb + Noun ”.

【 The rules 3-1-5】 Use the correct antonym group to name the mutually exclusive variable or the function of the opposite action .

【 Suggest 3-1-6】 Try to avoid numbers in names , Such as Value1,Value2 etc. , Unless logically It really needs to be numbered .

3.2 ordinary Windows Application naming rules

【 The rules 3-2-1】 Class and function names are combined with words starting with uppercase letters

【 The rules 3-2-2】 Variables and parameters are combined with words starting with lowercase letters .

【 The rules 3-2-3】 Constants are written in capital letters , Divide words with underscores .

img

【 The rules 3-2-4】 Prefix static variables s_( Express static).

img

【 The rules 3-2-5】 If you have to, global variables , The global variables are prefixed g_( Express global).

【 The rules 3-2-6】 Class's data members are prefixed m_( Express member), This prevents data members from being associated with The parameter of the member function has the same name .

img

4. Expressions and basic statements

4.1 Operator

【 The rules 4-1-1】 If there are more operators in the code line , Use parentheses to determine the order in which expressions operate , avoid Use the default priority .

4.2 Compound expression

【 The rules 4-2-1】 Don't write complex compound expressions .

img

4.3 for Statement loop control variable

【 The rules 4-3-1】 Don't be in for Modify the loop variable in the loop body , prevent for The cycle is out of control .

【 Suggest 4-3-1】 Suggest for The loop control variable value of the statement adopts “ Half open and half closed interval ” How to write it .

img

4.4 switch sentence

【 The rules 4-4-1】 Every case Don't forget to add break, Otherwise, multiple branches will overlap ( Unless you intentionally overlap multiple branches ).

【 The rules 4-4-2】 Don't forget the last one default Branch . Even if the program really doesn't need default Handle , You should also keep the statement default : break; It's not unnecessary , But to prevent others from mistaking Forget for you default Handle .

5. Constant ( Such as macro constants )

【 The rules 5-1】 Try to use intuitive constants to represent numbers or... That will appear many times in the program character string .

【 The rules 5-2】 Constants that need to be exposed are placed in the header file , Constants that do not need to be exposed are placed in the definition The head of the document . For the convenience of management , The constants of different modules can be stored in a common header file .

【 The rules 5-3】 If a constant is closely related to other constants , This relationship should be included in the definition , Instead of Some isolated values should be given .

( Two ) Write code that is easy to debug

common coding skill :

  • Use assert
  • Use as much as possible const
  • Develop a good coding style
  • Add the necessary comments
  • Avoid the pitfalls of coding

1. Use assert( Assertion )

Assertion assert It's only in Debug Version of the macro that works , It's used to check “ Should not be ” What happened .

At run time , If assert The parameter of is false , Then the program will stop ( Generally speaking, there will be prompt dialogue , Explain where it triggered assert).

2.const When decorating pointer variables :

  • const If you put it in * Left side , It modifies what the pointer points to , Ensure that the content pointed to by the pointer cannot be changed by the pointer . But the contents of the pointer variable itself are variable .
  • const If you put it in * To the right of , The modification is the pointer variable itself , It ensures that the contents of pointer variables cannot be modified , But what the pointer points to , It can be changed by the pointer .

3. Some perfect code examples

3.1 Simulate the implementation of library functions strcpy

strcpy When copying strings , In the source string \0 Copy it too

The return value is the first address of the target string

#include<stdio.h>
#include<assert.h>

char* my_strcpy(char* dest, const char* src)
{
    
	char* ret = dest;
	// Assertion 
	assert(src != NULL);
	assert(dest != NULL);

	while (*dest++ = *src++)
	{
    
		;
	}
    
	return ret;
}

int main()
{
    
	char arr1[20] = {
     0 };
	char arr2[] = "hello world";

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

3.2 Simulation Implementation strlen

strlen The return value of is an unsigned integer .

unsigned int my_strlen(const char* str)
{
    
	int count = 0;
	assert(str);
    
	while (*str != '\0')
	{
    
		count++;;
		str++;
	}
    
	return count;
}

int main()
{
    
	char arr[] = "hello world";

	printf("%u\n", my_strlen(arr));
	return 0;
}

This blog refers to 《 High quality C/C++ Programming 》, It explains how to write excellent C/C++ Code , Attached here are network disk resources , Interested partners can extract by themselves ! Extraction code :j6y6

Conclusion

Dear friends , It's fate to see here , I hope my content can bring you a little help , If you can, support it for three times !!! Thank you for coming here , We can learn and communicate together , Progress together !!! come on. !!!
img

原网站

版权声明
本文为[Xin Xiangrong]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/173/202206221516410996.html