4.1.4 Relational operators
In C + +, in addition to arithmetic operations that require arithmetic operators to subtraction the data, we sometimes need to manipulate the relationship between the data, that is, to compare the size of the two data to derive the size relationship between them. In the real world, comparisons of this size relationship are very common. For example, the tomato at this booth 5 yuan a catty, while the other one of the same tomato only sold 3 yuan a catty, 5 and 31 compared, we know that the second home of tomatoes cheaper. We say that the program is used to abstract and describe the real world, in order to express a comparison of this size relationship in the program, C + + specifically provides relational operators, including ">" (Greater Than), ">=" (greater than or equal), "<" (less than), "<=" (less than or equal to), "= =" (equals), "! =" (Not equal to).
Best practice: Note the difference between "= =" and "="
The two symbols are very similar in form, but the meaning of the expression is very diverse:
"= =" is a relational operator that determines whether two values are equal;
"=" is an assignment operator that assigns the variable on the left to the value on the right.
Because of the similarity of the two in form, if not pay attention to, it is easy to "= =" mistakenly write "=", or "=" mistakenly write "= =", resulting in code can not correctly express the designer's intentions, resulting in a program error. Even more troubling is that the compiler cannot find this cryptic semantic error, and even if it is misused in the code, the compiler will not give an error message, which makes it more difficult to prevent this error from happening. For example:
int A; // // // a = = 1 ; // The programmer had intended to compare a and 1 for equality // if (a = 1 << " a equals 1 " <<endl;}
From the actual meaning of this code, the whole is in gibberish, but from the execution of the code, but in line with our design expectations, successfully output "a equals 1". At the same time, the compiler does not report any error messages, which makes the error more secretive.
To put an end to the first misuse, we have to pay more attention to writing code. In addition, if you assign an initial value to a variable, it is best to do it at the same time as the variable is defined. For example:
// assigning an initial value while defining a variable // in this form, the compiler will help to find "int a = = 1;" Such an error int1;
For the second kind of misuse, we also need to be careful when writing code. In addition, one special case is that when we compare a variable to a constant, we'd better put the constant on the left side of the equal sign. This way, because constants cannot be assigned, even if we mistakenly write "=" as "=", the compiler will help us find this misuse. For example:
// equality Comparison of constant 1 with variable a // If you mistakenly write "if (1 = a)", you will be assigned a value of constant 1 . // and constants cannot be assigned, and the compiler reports an error message that helps us find this misuse if 1 = = a) {cout<<"a equals 1"<<Endl;}
In addition, although the compiler has no error message for this misuse, it has a corresponding warning message. When compiling the code, open the appropriate warning information switch (use the GCC compiler's-wall compilation option to turn on all warning switches), and note the compiler output warning message, can also be good to prevent the occurrence of such misuse.
The relational operator is a two-element operator whose function is to perform a relational operation on two operands, compare the size of two operands, or be equal, and the result of the operation is either true or false of the bool type. If the size relationship of the two operands conforms to the size relationship expressed by the operator, the result of the expression is true, and vice versa is false. For example:
// price of tomatoes on two stalls int 5 ; int 3 ; // A and B values are less than compared, but the value of a is greater than the value of B, does not conform to the meaning of the operator "<", // so the expression "a < B" evaluates to False, then assigns the value to Bcheap, // the value of Bcheap is also false, indicating that a is not cheaper than B bool bcheap = a < b;
In C + +, we usually use relational operators to determine whether a condition is set up, and then, with the conditional structure we will learn later, determine the execution path of the code, and treat the data differently to obtain different execution results. For example, we would like to say that Internet cafes prohibit minors under the age of 18 from entering:
intNAge =0; cout<<"Please enter your age:";//user Input AgeCin>>NAge;//Use the relational operator ">=" to determine whether the age of input is greater than or equal to//Judging whether adultsif(NAge >= -){ //the value of nage is greater than or equal tocout<<"Welcome to Mangrove Café"<<Endl;}Else //the value of nage is less than{cout<<"I'm sorry, minors are not allowed in ."<<Endl;}
In this code, we first let the user enter the age and save it to the nage variable, and then, in the if condition structure, use the ">=" relationship operator to compare it to 18. If the value of NAge is greater than or equal to 18, the value of the "NAge >= 18" expression is true, indicating that it is an adult, and the code goes into the statement after the if execution, outputting the welcome message. Conversely, it means a minor, and the code goes into the code behind the else and shuts it out.
Best practice: Do not use "= =" to determine whether two floating-point numbers are equal
Consider what the output of this code is:
float a = 0.1 ; if (A*10 = = 1.0 <<" 0.1*10 equals 1.0 <<ENDL;} else {cout << " 0.1*10 is not equal to 1.0 <<endl;}
Would it surprise you if I told you that the output of this code was "0.1*10 not equal to 1.0"? It's a bit of a surprise, but that's the truth. This is because in C + +, except for some special floating-point numbers (such as 0.5, 0.25, etc.), we cannot express most of the floating-point numbers accurately, so it is not safe to compare two floating-point numbers for equality. Although on the surface, the value of a is 0.1,a*10 equals 1.0 is certain, but because the floating point number a can not accurately express the value of 0.1, there is a very small error, when a certain operation, the error will accumulate to a detectable degree, then use "= =" When compared with its theoretical results, the results may be equal or unequal. And as to which one, it depends on the computer hardware and compiler optimization settings. The result of this code on a computer may be "0.1*10 not equal to 1.0", but the result of the output on another computer may be "0.1*10 equals 1.0". Therefore, to ensure consistent code behavior, do not use "= =" in your code to compare two floating-point numbers for equality.
What if you really need to compare two floating-point numbers in your code? The simplest method is to set an allowable error value (according to our accuracy requirement), when the absolute value of the difference of two floating-point is within this error range, the two floating-point numbers are considered equal, whereas the two floating-point numbers are considered unequal. For example, the code above can be modified to look like the following to ensure consistent code behavior.
floatA =0.1;//equal range of errorsConst floatFepsilon =0.0001;//determines whether the absolute value of the difference of two floating-point numbers (obtained with the Fabs () function) is within the error range//if it is, the two floating-point numbers are considered equalif(Fabs (A *Ten-1.0) <Fepsilon) {cout<<"0.1*10 equals 1.0 ."<<Endl;}Else //Conversely, the two floating-point numbers are considered unequal{cout<<"0.1*10 Not equal to 1.0"<<Endl;}
With this rewrite, the equivalent code for this floating-point number can produce consistent and correct results on any computer.
4.1.5 Logical operators
When dealing with complex transactions, we often need to decide whether or not to perform an action based on multiple criteria. For example, the door of an internet café is affixed with such a note:
"Only people who are 18 years old and have money in their pockets can enter the Internet cafes. ”
Here "and", in fact, "18 years old" and "pocket money" the two conditions of "and" the logical operation, only these two conditions at the same time to meet the conditions, only to be able to perform "access to the Internet bar" operation. Like "and" This is a logical operation of the two conditions of the verb, in C + +, we use logical operators to express.
The logical operators provided by C + + include the following three types.
L! (non): Calculates the logical non of operands.
L && (with): Calculates the logic of two operands with.
L | | (OR): Calculates the logical OR of two operands.
Which, "!" is a unary operator that can only be placed before an operand of a single bool type, taking a non-operation and obtaining the opposite logical value. For example:
BOOL true; // defines a variable of type bool Bflag and assigns a value of true // The operand bflag is not manipulated, the result of the entire expression is false, // contrary to the value of the operand bflag !bflag;
"&&" and "| |" are two-dollar operators that concatenate the operands of two bool types and logically perform the resulting value of the bool type as the value of the entire expression. The function of "&&" is to calculate the logic of the two operands, which means that the value of the entire expression is true only if the value of the two operands is true, otherwise false. "| |" The function is to calculate the logic of the two operands or, as long as one of the two operands is true, the value of the entire expression is true, otherwise false.
In specific programming practice, logical operators are often used in conjunction with relational operators and are used to express complex conditional logic judgments in conditional structures. For example, we should evaluate the students ' assessment grade according to the students ' Chinese and maths scores, the rule is: if the language and mathematics scores are 60 or more, then "qualified", on the basis of "qualified", as long as one of the results is more than 85 points, is "excellent". In C + +, we can express this complex logical judgment in this way:
cout<<"Please enter your students ' language and math scores (e.g.,:";//define variables to save the input dataintNCHS =0;intNmath =0;//enter data and save to variableCin>>nchs>>Nmath;//evaluating the level of logical judgment of a variable//first of all, to determine whether two scores are 60 points above, to achieve the "qualified" standardif((Nchs >= -) && (Nmath >= -)){ //On the basis of "qualified", judge whether there is a score of more than 85, to achieve the "excellent" standard if((Nchs >= -)|| (Nmath >= -) ) {cout<<"Excellent"<<Endl; } Else //if the standard of "good" is not met, it is "qualified "{cout<<"qualified"<<Endl; }}Else //if the "qualified" standard is not met, it is "unqualified"{cout<<"not qualified"<<Endl;}
Here, we use the "&&" operator to "NCHS >= 60" and "Nmath >= 60" with the "and" operation, that is, the values of both expressions are true, the final result is true. In other words, in order for the final result to be true, that is, to achieve the "pass" standard, it is necessary to require "NCHS >= 60" and "Nmath >= 60" The values of both expressions are true, and in order to make the values of both expressions true, Naturally, the value of NCHS and Nmath is required to be greater than 60 at the same time, thus expressing the logic judgment of "qualified" standard of "Chinese and maths scores are more than 60 points". Only to meet this logic judgment, to meet the eligibility criteria, to enter the next level of judgment whether "excellent"; otherwise, as long as any one of NCHS and Nmath less than 60, can not satisfy this logic judgment, the program will go to the Else branch output "unqualified" prompt. In the "| |" When the operator judges the "good" condition, the end result is true as long as any of the two expressions "Nchs >= 85" and "Nmath >= 85" are true. In other words, as long as any one of the NCHS and Nmath is greater than 85, the end result is true, which also expresses the "good" standard of "as long as one of the scores is above 85".
Best practices: Note "&&" and "| |" The "logical short circuit" mechanism of the operator
These two operators are used to perform logical operations on multiple expressions, resulting in the final result of multiple expressions having been calculated. When the operation is performed, if the final result of the entire expression can be determined by virtue of the value of the previous expression, C + + will no longer continue to operate on the remainder of the expression, but rather a direct shortcut to return the value of the entire expression that has been obtained. This mechanism is called a "logical short circuit", that is to take a shortcut.
This explanation is still a bit abstract, let's take the example above to see "short-circuit mechanism" in the end is how to "cut corners".
if - ))
In this conditional judgment, we use the "&&" operator for "NCHS >= 60" and "Nmath >= 60" for "and" operations, if the value of NCHS is less than 60, that is, the first conditional expression "NCHS >= 60" value is False , regardless of whether the value of the "Nmath >= 60" expression later is true or false, we have been able to determine that the value of the entire expression will be false,c++ with false as the value of the entire expression, skipping to the back "Nmath >= 60" To end the calculation of the entire expression directly. Therefore, in order to reduce the computational efficiency, C + + directly skips over the calculation of the second relational expression, copying a shortcut.
When you use the ' | | ' This "logical short circuit" is also present in the "or" operation. For example:
if - ))
In this with "| |" operator, if the value of NCHS is greater than or equal to 85, the value of the first relational expression "Nchs >= 85" is true, and you can determine that the value of the entire expression is true,c++ also skips over the second relationship expression "Nmath >= 85 , and with true as the value of the entire expression, directly ends the evaluation of the entire expression.
In addition to reducing unnecessary calculations and, to a certain extent, increasing efficiency, the greater significance of a "logic short circuit" is that it can reduce the level of logical judgment in some cases (the premise of a condition before a condition is judged). For example, if we want to use the member variable of a struct pointer as a condition, we must first determine whether the struct pointer is valid, then we can judge the pointer's member variable. Without a "logic short" mechanism, our code should be written as:
human* p = nullptr; // ... .. if (nullptr! = p) // first determine if the pointer is valid { // then determine if the pointer's member variable meets the criteria // The second condition is judged by the first condition if - ) { // ... }}
And if the "logical short circuit" mechanism is used, this condition can be simplified to:
human* p = nullptr; // ... .. if - )){ // ...}
This will also determine whether the pointer p is a null pointer when the condition is judged, and if the first condition satisfies, it will continue to judge whether its member variable satisfies the condition. Achieve the same conditional judgment, but reduce the level of logical judgment, simplify the code, and this is the "logical short-circuit" mechanism of the main application scenario.
Hello, C + + (17) 0.1*10 not equal to 1.0--4.1.4 relational operator 4.1.5 logical operator