Readers may suspect that something as simple as an if, a for, a while, a goto, or a switch should also be about programming style, is it a fuss?
I really find that many programmers write expressions and basic statements in the wrong way, and I have made similar mistakes myself.
Both expressions and statements belong to the C++/C phrase structure syntax. They seem simple, but they are more dangerous when used.
This chapter concludes some of the rules and recommendations for the correct use of expressions and statements.
Precedence of the 4.1 operator
There are dozens of operators in the c++/c language, and the precedence of operators and associativity is shown in table 4-1. Note that the unary operator +-* has precedence over the corresponding two-dollar operator.
Priority level |
Operator |
Binding law |
Rank from high to low |
() []->. |
From left to right |
! ~ + +--(type) sizeof +-* & |
from right to left |
* / % |
From left to right |
+ - |
From left to right |
<< >> |
From left to right |
< <= > >= |
From left to right |
== != |
From left to right |
& |
From left to right |
^ |
From left to right |
| |
From left to right |
&& |
From left to right |
|| |
from right to left |
?: |
from right to left |
= + = = *=/=%= &= ^= |= <<= >>= |
From left to right |
Table 4-1 Precedence and associativity of operators
L
"Rule 4-1-1
"If there are more operators in the line of code,Use parentheses to determine the order in which the expressions are operated, and avoid using the default precedence. Since it is more difficult to memorize table 4-1, in order to prevent ambiguity and improve readability, it should be use parentheses to determine the order of operations for an expression. For example:Word = (High << 8) | Low if ((a | b) && (A & c))
4.2 Compound expression An expression such as a = b = c = 0 is called a composite expression. The reasons for the existence of compound expressions are: (1) Concise Writing, (2) can improve the efficiency of compilation. But to prevent the misuse of compound expressions. L
"Rule 4-2-1
"Do not write complex expressions that are too complicated. For example: i = a >= b && c < d && C + F <= g + H; // Compound expression too complex l
"Rule 4-2-2
"Do not have multiple-purpose compound expressions. For example: D = (A = B + c) + R; The expression asks for a value and a value of D. Should be split into two separate statements: a = B + C; D = A + R; L
"Rule 4-2-3
"Do not confuse a compound expression in a program with a "real mathematical expression." For example: if (a < b < c) //A < b < C isA mathematical expression instead of a program expression does not represent if ((a<b) && (b<c)) it becomes an inexplicable if ((a<b) <c)
4.3 If statement The if statement is the simplest and most commonly used statement in the C++/C language, yet many programmers write an if statement in an implicitly incorrect way. This section takes the "compare with 0 value" as an example to start the discussion.
4.3.1 Boolean variable and 0 value comparisonL
"Rule 4-3-1
"You cannot compare a Boolean variable directly with True, false, or 1 or 0. Based on the semantics of the Boolean type, the 0 value is false, and any non-0 values are true (true). There is no uniform standard for what the value of true is. For example, Visual C + + defines true as 1, whereas Visual Basic defines true as-1. Suppose the Boolean variable name is flag, it is compared with 0 valueThe standard if statement is as follows: if (flag) //Express flag as Trueif (!flag) //means flag is falseOther uses are in bad style, for example: if (flag = = TRUE) if (flag = 1) if (flag = = FALSE) if (flag = 0)
Comparison of 4.3.2 Integer variable and 0 valueL
"Rule 4-3-2
"You should use an integer variable with the = = "or"! = "Direct comparison with 0"。 Suppose the integer variable is named Value , which is compared with the 0 valueThe standard if statement is: if (value = = 0) if (value!= 0) cannot imitate the style of a Boolean variable and write as if (value) //Can make people misunderstand value is a Boolean variableif (!value)
4.3.3 floating-point variable and 0 value comparisonL
"Rule 4-3-3
"You cannot use a floating-point variable with the = = "or"! = "Compared with any number。 Be aware that there are precision restrictions on variables, whether float or double. So be sure to avoid using the floating-point variable "= =" or "! = "In contrast to numbers, it should be managed to be converted into" >= "or" <= "forms. Assuming that the name of the floating-point variable is x, you shouldif (x = = 0.0) //Implied error comparisonConvert to if ((X>=-epsinon) && (X<=epsinon) Epsinon is the allowable error (i.e. precision).
4.3.4 pointer variable and 0 value comparisonL
"Rule 4-3-4
"You should use the pointer variable with the = = "or"! = "Comparison with null。 the 0 value of the pointer variable is "NULL" (recorded as null). Although the value of NULL is the same as 0, the two meanings are different. Suppose the name of the pointer variable is p, it's compared to the 0 valueThe standard if statement is as follows: if (p = = null)//p is explicitly compared with NULL, emphasizing that p is a pointer variable if (P!= NULL)Don't write if (p = = 0)//easy to misunderstand p is an integer variable if (P!= 0) orif (p) //Easy to misunderstand P is a Boolean variable. if (!p)
4.3.5 of the if statement Sometimes we might see if (NULL = p) In such an odd format. It is not a program that is written incorrectly, it is the programmer who intentionally reverses p and null in order to prevent the IF (P = null) from being mistakenly written as if (P = null). The compiler considers if (P = null) to be legitimate, but indicates that if (NULL = p) is wrong, because NULL cannot be assigned. There are times in programs where you encounter The combination of If/else/return, should be the following bad style of the program if (condition) return x; return y;Rewritten as if (condition) { return x; } Else {return y; or rewrite it to a more concise return (condition x:y);
Efficiency of 4.4 circular statements in the C++/C Loop statement, the FOR statement is used most frequently, while the while statement is followed by a do statement that is rarely used. This section focuses on the efficiency of the circulatory body. The basic method to improve the efficiency of circulating body is to reduce the complexity of the circulating body. L
"Suggested 4-4-1
"In multiple loops, if possible, the longest loop should be placed in the outermost layer, and the shortest loop should be placed at the outer layers to reduce the number of times the CPU has been cut across the loop layer. For example, the efficiency of example 4-4 (b) is higher than that of the example 4-4 (a).
For (row=0 row<100; row++) {for (col=0; col<5; col++) {sum = sum + A[row][col];}} |
For (col=0 col<5; col++) {for (row=0; row<100; row++) { sum = sum + A[row][col]; }} |
Example 4-4 (a) Low efficiency: long cycle in the outermost example 4-4 (b) High efficiency: Long cycle in the outermost layerL
"Suggested 4-4-2
"If there is a logical judgment in the loop, and the number of cycles is large, it is advisable to move the logical judgment outside the loop body. Example the procedure for 4-4 (c) performs more N-1 logical judgements than the example 4-4 (d). And because the former to make logical judgments, interrupted the cycle of "pipeline" operations, so that the compiler can not optimize the process of the cycle, reducing efficiency. If n is very large, it is best to use the example 4-4 (d) to improve efficiency. If n is very small, the efficiency difference between the two is not obvious, using the example 4-4 (c) is better, because the program is more concise.
For (i=0 i<n; i++) {if (condition) dosomething (); else dootherthing (); } |
if (condition) {for (i=0, i<n; i++) dosomething (); } else {for (i=0; i<n; i++) D Ootherthing (); } |
table 4-4 (c) inefficient but concise table 4-4 (d) High efficiency but not concise procedures
4.5 loop control variable for statement L
"Rule 4-5-1
"You cannot modify the loop variable in the For loop body to prevent the for loop from losing control. L
"Suggested 4-5-1
"Suggestions The value of the loop control variable of the For statement is written in "Half open and half closed interval". Example the X value in 4-5 (a) belongs to the half open semi closed interval "0 =< x < N", the interval of beginning to end point is N, and the number of cycles is n. Example the X value in 4-5 (b) belongs to the closed interval "0 =< x <= N-1", the interval between the beginning and the end is N-1 and the number of cycles is N. By contrast, the example 4-5 (a) is more intuitive, although the two functions are the same.
for (int x=0; x<n; x + +) {...} |
for (int x=0; x<=n-1; x + +) {...} |
Example 4-5 (a) the cyclic variable belongs to a half open semi-closed interval example 4-5 (b) The cyclic variable belongs to the closed interval
4.6 Switch statement Why do I need a switch statement with an IF statement? A switch is a multiple-branch selection statement, and an if statement has only two branches to choose from. Although it is possible to use nested IF statements to implement multiple branching selections, such programs are tedious to read. This is the reason for the switch statement to exist. the basic format of the switch statement is:Switch (variable) {case value1: ... break, case value2: ... break; . ..Default: ... break; } l
"Rule 4-6-1
"Each do not forget to add a break at the end of the case statement, or you will cause multiple branches to overlap (unless you intentionally make multiple branches overlap). L
"Rule 4-6-2
"Don't forget the last one. Default Branch. Even if the program really does not need default processing, it should also retain the statement Default:break; This is not superfluous, but to prevent others from mistaking you for default processing.
4.7 goto Statement Since the promotion of structured design, Goto has become a controversial statement. First of all, because the goto statement can be flexible to jump, if not restrictive, it does break the structural style of design. Second, goto statements often bring errors or pitfalls. It may skip the construction of some objects, the initialization of variables, the important calculation, and so on, for example:Goto State; String S1, S2; //Goto skippedint sum = 0; Be goto skip ... state: ... If the compiler cannot detect this type of error, use each time goto statements can leave a hidden danger. Many people suggest abolishing the C++/C goto statement, Ehin. But realistically speaking, the mistake is the programmer's own cause, not Goto's fault. The goto statement has at least one magical avatar that jumps from the multiple loops to the outside without having to write a number of break statements; For example{ ... {... .. {... .. goto error; } }Error: ... Like a building on fire, too late from the staircase level down, can jump out of the pit from the window. So we advocate less use, careful use Goto statement, not disabled.