A program design
To avoid errors, first start with a good design. For program design, consider two features of the program:
1 Simply
Most common errors are derived from unnecessary complex ingredients in programming. A good design should reflect the problem
The requirements of the body do not have to add unnecessary features to deliberately pursue "satisfying future needs". In fact, simple
Single elegant design is better to meet future needs than those complex design.
2 coupling
Decoupling sexuality is used to measure the dependence between different objects. Loose coupling procedures easy to understand and implement
Easy to test and maintain, and this program contains a small possibility of errors, and error is also easier to discover and clear.
Two-programming style
Programming style is personal problems, with great randomness. A good programming style not only makes the code easy to understand, and it is easy to
debugging. Good programming style includes:
1 clearly write code
If there is no need, try not to use the advanced features in the language because these features are not easy to understand and debug. Make
Writing code is not easy to make mistakes with most of the programmers can understand and easy to understand and maintain.
2 Writing a structure good code
The most basic debugging information that can be obtained when the program crashes is the source code file, the line number and one adjustment of the problem.
Use a stack. The calling stack is the most helpful part of the debugger, which provides the context that occurred in the error.
That is, a function call sequence with parameters. The better the code structure you write, the more information you can give you.
3 use good identifier
A good name can make your code more easily understood and maintained. Popular Hungarian Name Method (Hungarian Notat
ION) In fact, it is actually combining the meaning of the identifier and representation. Now, Hungarian nomenclature shows a lot of
Limitations, Hungarian nomenclature is too valued, and the expression information of a variable is incomplete, in fact
Without how much useful information, it makes the code difficult to read, difficult to maintain. A good named tradition is an indication
The amount of action is to check its definition when needed, and clearly indicate that a variable is global, local
Still member data. Dependency variables are more useful and reliable than dependent Hungarian prefix.
A good name can generalize the meaning of the entity represented by the identifier in a usual language. Select classes, functions, change
The following principles can be considered when the name is:
Take a simple descriptive name, a good name briefly summarizes the meaning of this identifier representative.
Avoid shorthabing, short-handed identifier is difficult to read and memorize, try to use a complete word of mixed case.
Avoid the text of the similarity to avoid confusion.
Avoid adopting general or random names, but should use the actual name. For if you want from button
Brand map button, take a CBitmapButton instead of cmybutton.
4 use simple statement line
In the VC, one line can write multiple statements. But debugging is facing, too complicated, difficult to debug. therefore
From the perspective of debugging, each statement should be a row.
5 use unified arrangement
The unified arrangement makes the definition and statement of the class, variables more obvious.
6 Clear writing with parentheses
You don't necessarily remember the priority and combination of various operators, and use excess parentheses does not affect your compilation.
The transceiver code. So if you can't determine if you need parentheses, add it.
7 use good notes
Using a good note can make your code difficult to make mistakes, and it is convenient for other programmers to read, easy to understand and maintain
.
I should pay attention to the problem when writing programs
1 Take advantage of VC features
The following techniques can be used to take advantage of the characteristics of the VC compiler:
(1) Use const instead #define to create constants;
(2) Use enum instead #define to create a constant collection;
(3) instead of #define with the inline function; these three techniques are used in C instead of C pre-processed. The problem with pre-processing is that the compiler for the pre-processor
I don't know anything, so you cannot check the errors and inconsistent places with data types. Prerequisite name is not
In the symbol table, therefore cannot use the debug tool to check the pretreatment constant. Similarly, the pretreatment macro is compiled into
You cannot use debug tools to track. The compiler fully understands const, enum, and inline statements, so that can be compiled
A warning will be issued to the problem.
But preprocessing plays an important role in many debuggers. Debug code often needs to be in the non-debug code
To different behaviors, the most effective way is to let preprocessing to create different code.
(4) Use new and delete instead of Malloc and Free;
In terms of creating objects, types of security and flexibility. Use new / delete better than Malloc / Free. In addition,
New can be overloaded to provide greater flexibility.
(5) Instead of STDIO with an input and output stream (iostreams).
Use C input and output stream (<< and >>) without using C standard input and output library (PrintF / Sprintf and S
CANF / SSCANF is conducive to security and scalability. From the perspective of debugging, the standard input output function is the largest
The problem is that the compiler does not detect any type detection on the control flow parameters, and any problem in the input and output flow can be
Detected when compiling.
2 use header files
To declare all shared external symbols in the header file, and reserve the parameter name in the function prototype. Put all
Sharing definitions in the header file, do not see the extern keyword in the .cpp file.
3 initialization variables
Be sure to initialize them before using variables. Use variables will definitely generate errors before initialization.
. You usually do not need to initialize the object, and the pair of data should be initialized in the constructor. Must be clear
The array and data structures allocated in the stack were initialized. For objects, each need initialization should be initialized
Data member. Since the use of the variable is checked by an optimizer, the local variable that is not initialized is detected.
The cloth version is better than the debug version.
4 use Boolean expressions
C Boolean type: Bool, value is True and False, size is one byte.
Windows programs typically use the BOOL type. Defined as follows:
Typedef int BOOL;
#define false 0
#define True 1
In C , a Boolean expression is false if it is 0, and others are true. Therefore, the Boolean expression should be
This check is to ask if you don't check if it is true.
5 use handles and pointers
When you initialize a pointer, or let it point to a valid memory address, or set to 0 (empty pointer)
Avoid pointer to the invalid address. Recycling this pointer when the object refers to the pointer, and is being
It is handled in front of the release. The processing of the handle is the same as the pointer.
6 Use reference instead of pointer to do parameters
The parameters that do functions with pointers can be transmitted, which is very flexible, but it is easy to forget the beginning of the pointer.
Start. The reference is an alias of the object, it must be associated with a valid object, there is no empty and not initialized
Quote. When you receive a reference parameter in a function, it is certain that this is a valid object. Program
Parameters are more robust than using pointers.
7 Mandatory Type Conversion (CAST)
When the mandatory type conversion of the data type is called, the corresponding constructor or conversion function will be called to create a
A new type of temporary object. The correct type conversion of the pointer eliminates a compilation error, but does not change the pointer.
Forced type conversion destroys the functionality of the compiler for type inspection, which is the most effective mechanism for compilers to find errors. To ensure security, each forced type conversion requires manual type check. To try to avoid strong
Type conversion, you can: avoid using polymorphism data type; use a more wide base class; provide special access
Function; let the compiler implicitly handled types of measures.
8 use constructor and destructor
The constructor needs to allocate memory, create a resource or open file, which is not always successful. structure
The function does not return value and does not directly display the wrong method. A common method (used in many MFC classes)
Divide object creation into two steps: first step, let the constructor initialize the object in a way that is not wrong;
Let some of the initialization functions (such as init or open) work, this step may be wrong. Another method is
Using an exception in the function: The first step is to initialize the object in a way wrong; the second step, it may be in the TRY segment
Error code initializes the object; the third step, the abnormality is handled in the CATCH code. If an abnormality occurs, it will be
Clear the allocated resource in the function, and throw an exception again.
A key detail of exception handling is an exception thrown during the stack to terminate the entire application.
. The destructive function is often called when processing an exception, so the destructuring function is easily error, and must ensure the destructive function
The exception is processed in the destructor. To ensure that the analytical function of the base class is a virtual function. In this way, even if the object is one
A pointer to the base class, which also calls the secting function of the derived class. Otherwise, it will cause resource leaks (Resource
Leak).