Chapter 11 Other Programming Experience
11.1 Using const to improve the robustness of functions
Seeing the const keyword, the C programmer first thinks of the constant constant. This is not a good condition reflection. If you only know the constant defined with const, it is equivalent to only use gunpowder to make firecrackers. Const greater charm is that it can modify the parameters, return values, or even function of the function.
Const is Constant's abbreviation, "constant" means. Things that are modified by const are mandatory, prevent accidents, can improve the robustness of the program. So many C programming books Suggestions: "Use constly you need".
11.1.1 Parameters of the const modified function
If the parameter is used, no matter what the data type is, no matter whether it adopts "pointer" or "reference delivery", you cannot add const modification, otherwise the parameter will lose the output function.
Const can only modify the input parameters:
u If the input parameter is adopted "Pointer Transfer", then CONST modification prevents accidentally change the pointer to protect.
For example, StringCopy functions:
Void stringcopy (char * strdestination, const char * strsource);
STRSource is an input parameter, and strDestination is the output parameter. After adding CONST modification, if the statement in the function is trying to change the content of strsource, the compiler will indicate an error.
u If the input parameter is "value passed", since the function will automatically generate temporary variables to copy this parameter, the input parameter has no protection, so do not add const.
For example, don't write the function void func1 (int x) as a VOID FUNC1 (Const Int X). Similarly, do not write the function void func2 (a a) as Void Func2 (Const A A). Where A is a user-defined data type.
u For parameters of the non-internal data type, the function is determined in the end of the function of the VOID FUNC (A A). Because the functionality of the A type of temporary objects will be used to copy parameter A, and the temporary object constructs, copying, and secting processes will consume time.
In order to improve efficiency, the function declaration can be changed to Void Func (A & A), because "reference delivery" only borrows the alias of the parameter, there is no need to generate temporary objects. However, the function Void Func (A & A) has a disadvantage: "Reference Pass" is likely to change the parameter a, which is our undesirable. Solving this problem is easy, add const modification, so the function will eventually become Void Func (Const A & A).
In this kind, whether Void Func (INT X) should be rewritten as Void Func (Const Int & X) to increase efficiency? There is no need, because the parameters of the internal data type do not have construction, the process of sect, and the replication is very fast, "value transfer" and "reference delivery" are almost fairly.
The problem is so lingering, I have to summarize the use of "const &" modified input parameters, as shown in Table 11-1-1.
For input parameters for non-internal data types, "value delivery" should be changed to "const reference", and the purpose is to improve efficiency. For example, Void Func (a a) is changed to Void Func (Const A & A).
For input parameters for internal data types, do not change the "value to" to "Const reference". Otherwise, it will not only improve the efficiency, and the understandability of the function is reduced. For example, Void Func (INT X) should not be changed to Void Func (Const Int & X). Table 11-1-1 Rule of "const &" modified input parameters
11.1.2 Return value with const modified function
u If the value is returned to the value of the "pointer" mode, the content return value (ie, the pointer) cannot be modified, which can only be assigned to the same type of CONST modified.
For example functions
Const char * getString (void);
The following statement will appear compilation:
CHAR * STR = getString ();
The correct usage is
Const char * str = getString ();
u If the function return value uses "Value Transfer Method", since the function is copied to the external temporary storage unit, there is no value.
For example, don't write the function INT GetInt (Void) into const Int GetInet (VOID).
Do not write the function a geta (void) as a CONST A GETA (Void), which is a user-defined data type.
If the return value is not an internal data type, the function A geta (void) is indeed increasing efficiency. But it is necessary to be careful at this time, be sure to figure out the "copy" of the function wants to return an object or returns "alias", otherwise the program will be wrong. See Section 6.2 "Return Value Rules".
u Function Return Value is not much in the case of "reference delivery", which typically only appears in the assignment function of the class, and the purpose is to achieve chain expression.
E.g
Class A
{...
A & Operate = (const a & other); // assignment function
}
Objects A A, B, C; // A, B, C is A
...
A = b = c; // Normal chain assignment
(a = b) = c; // abnormal chain assignment, but legal
If the return value of the assignment function is added to const modification, the content of the return value is not allowed to be changed. In the above example, statement a = b = c is still correct, but the statement (a = b) = c is illegal.
11.1.3 Const member functions
Any function that does not modify the data should be declared as a const type. If you write a Const member function, you accidentally modify the data member, or call other non-Const member functions, the compiler will point out errors, which will undoubtedly improve the robustness of the program.
In the following procedure, the member function getCount of class stack is only used to count, and the getCount should be a const function from logically. The compiler will point out errors in the getCount function.
Class Stack
{
PUBLIC:
Void Push; INT ELEM
INT POP (Void);
INT getCount (void) const; // constist member function
Private:
INT m_num;
INT M_DATA [100];
}
INT Stack :: getCount (void) Const
{ m_num; // Compiling errors, attempt to modify data members m_num
POP (); // Compiling errors, trying to call non-Const functions
Return m_num;
}
The statement of the Const member function looks whims: Const keyword can only be placed in the end of the function declaration, which is probably because it has been occupied elsewhere. 11.2 Improve the efficiency of the program
The time efficiency of the program refers to the speed of operation, and the spatial efficiency is the condition of the program occupies memory or existence.
The global efficiency refers to the efficiency of standing throughout the system, and local efficiency refers to the efficiency considered at the point of view of the module or function.
l [Rules 11-2-1] Do not pursue the efficiency of the procedure, should improve the efficiency of the program under the premise of satisfying the quality factors such as correctness, reliability, robustness, and readability.
l [Rule 11-2-2] is mainly based on the global efficiency of the program, and improve local efficiency is secondary.
l [Rules 11-2-3] When the efficiency of the optimization procedure should first identify the "bottleneck" of the restriction efficiency, do not optimize the insignificant.
l [Rule 11-2-4] First optimize the data structure and algorithm, and then optimize the execution code.
l [Rules 11-2-5] Sometimes time efficiency and space efficiency may be opposite, at this time, it should be analyzed and appropriate compromise. For example, spend some memory to improve performance.
l [Rules 11-2-6] Do not pursue compact code, because the compact code does not produce efficient machine code.
11.3 Some beneficial advice
2 [Recommendation 11-3-1] Be careful to write errors when the operators that are not easy to distinguish.
We often write "==" to "=", like "||", "&&", "<=", ">", is also very prone to "loss 1" mistakes. However, the compiler does not necessarily automatically point out such an error.
2 [Recommendation 11-3-2] Variables (pointers, arrays) should be initialized after being created to prevent use of uninitialized variables from being used as right values.
2 [Recommendation 11-3-3] When the initial value of the core variable, the default value is wrong, or the accuracy is not enough.
2 [Recommendation 11-3-4] Beware of the incorrect transition of data type. Try to use explicit data type conversion (let people know what happened), avoid making the compiler slidably implicitly converted.
2 [Recommendation 11-3-5] Beware of overflow or underflow, and the subscript of the array.
2 [Recommendation 11-3-6] Be careful to write the wrong handler, when the heart error handler itself is incorrect.
2 [Recommendation 11-3-7] Beware of the file I / O error.
2 [Recommendation 11-3-8] Avoid writing skills high code.
2 [Recommendation 11-3-9] Do not design, very flexible data structure.
2 [Recommendation 11-3-10] If the original code quality is better, try to multiplex it. But don't patch a very bad code, you should rewrite.
2 [Recommendation 11-3-11] Try to use the standard library function, do not "invent" existing library functions.
2 [Recommendation 11-3-12] Try not to use the variables close to specific hardware or software environment.
2 [Recommendation 11-3-13] Set the selection of the compiler to the most strict state.
2 [Recommendation 11-3-14] If possible, use PC-LINT, LOGISCOPE and other tools to conduct code review.