✅Author’s profile: Hello everyone, I’m Xiao Yang🐳 Hope you all support 🥰 and make progress together!****

blog🔥 series of columns: Xiao Yang takes you to play with the C language [primary]

Hello everyone! I am Xiao Yang. Xiao Yang made a big summary of the knowledge of operators in the C language. I think everyone should gain a lot after reading it carefully. So today, I will summarize the content of expression evaluation, which is convenient for my review and can also help everyone. Come on, dream catcher!

Article directory

## ✍ [Expression] evaluation

**The order in which expressions are evaluated is determined in part by the precedence and associativity of operators.**

**Likewise, the operands of some expressions may need to be converted to other types during evaluation.**

## ✍1, implicit type conversion

**C integer arithmetic operations are always performed with at least the precision of the default integer type.**

**To achieve this precision, character and short operands in expressions are converted to ordinary integers before use, a conversion called integer promotion.**

**The meaning of integer promotion:**

**the integer operation of the expression should be performed in the corresponding computing device of the CPU. The byte length of the operand of the integer arithmetic unit (ALU) in the CPU is
generally the byte length of the int, and it is also the byte length of the CPU. The length of the general register.**

**Therefore, even the addition of two char types is actually first converted to the standard length of the integer operand in the CPU when executed by the CPU
.**

**It is difficult for general-purpose CPUs to directly add two 8-bit bytes directly (although
there may be such byte addition instructions in machine instructions). Therefore, various integer values whose length may be less than the length of int in the expression must be
converted to int or unsigned int before they can be sent to the CPU to perform operations.**

**In order to better understand its usage, Xiao Yang explained it through several examples.**

**Example:**

#include<stdio.h> int main() { char a = 5; char b = -13; char c = a + b; printf("%d", c); return 0; }

**The CPU performs the operation flow:**

**the values of a and b are promoted to ordinary integers, and then the addition operation is performed.
After the addition is complete, the result is truncated before being stored in c.**

**Expansion: Truncation is when assigning data of a large type to data of a small space type, truncation occurs because the space of the small type is insufficient.**

**Here, Xiao Yang will first expand a little knowledge for everyone: how to improve the overall situation?**

**Answer: Integer promotion is promoted according to the sign bit of the data type of the variable.**

**In order to better understand how the shaping promotion is carried out, Xiao Yang gave the following examples of shaping promotion.**

**The integer promotion of negative numbers
char c1 = -1;
there are only 8 bits in the binary bit (complement) of the variable c1:
1111111
Because char is a signed char,
when the integer is promoted, the high bit is supplemented with the sign bit, which is 1
promotion The result after that is:
11111111111111111111111111111111**

**Positive integer promotion
char c2 = 1;
there are only 8 bits in the binary bit (complement) of variable c2:
00000001
Because char is a signed char
, when the integer is promoted, the high-order supplementary sign bit is 0
after promotion The result is:
00000000000000000000000000000001**

Remember: unsigned integer promotion, high-order fill with 0

**Knowing how to upgrade the char type and the short short integer type, then go back to the first instance before, what is the output result of the program of this instance, everyone should know how to calculate and get the correct result the answer.**

**By printing out the example results:**

**Analysis process:**

**The result obtained through the above process is the same as the result printed by the program code, we can know that there is no error in the process.**

**At this point, there may be some friends who still don’t understand the knowledge point of integer conversion. Don’t worry, Xiao Yang will give another example.**

**Example 2:**

#include<stdio.h> int main() { char a = 0xb6; short b = 0xb600; int c = 0xb6000000; if (a == 0xb6) printf("a"); if (b == 0xb600) printf("b"); if (c == 0xb6000000) printf("c"); return 0; }

**Friends, can you know the output of this example? If you can, it means that you have mastered the knowledge point of shaping improvement; if not, don’t be discouraged, just read this knowledge point several times.**

**Explanation: In fact, this example is not difficult. In the example, a and b need to be reshaped, but c does not need to be reshaped. After a and b are reshaped, they become negative numbers, so the expression a==0xb6 , b= The result of =0xb600 is false, but the integer promotion of c does not occur, then the result of the expression c==0xb6000000 is true, and the result of the program output is c.**

**Example output:**

## ✍2, arithmetic conversion

If the operands of an operator are of different types, the operation cannot proceed unless one of the operands is converted to the type of the other . The following hierarchy is called ordinary arithmetic transformations.

long double multiple-precision floating-point type or long-precision floating-point type

double double-precision floating-point type

float single-precision floating-point type

unsigned long int unsigned long

long int long

unsigned int unsigned int

int

**If the type of an operand is lower in the above list, the operation is performed first by converting to the type of the other operand.**

**If the double double-precision floating-point number and the int integer number are operated on, the int type data should be promoted and converted to double type data first, and then the corresponding operation will be performed. After the operation is completed, the result will be truncated and then stored. in c.**

#include<stdio.h> int main() { double a = 5.0; int b = -13; int c = a + b; printf("%d", c); return 0; }

**WARNING: Arithmetic conversions have to be reasonable, otherwise there are some potential risks** .

**Example:**

# include <stdio.h> int main () { float f = 3.14 ; int num = f; //Implicit conversion, there will be loss of precision printf ( "%d" , num); return 0 ; }

**Example output:**

**Finally, Xiao Yang systematically summarizes the arithmetic conversion:**

**Arithmetic conversion is that when two different types of data are operated on, they need to be interpreted as the same type for calculation.**

**For example, signed and unsigned, the signed data will be treated as unsigned and involved in the operation, -1 will be interpreted as a large number, and the integer and floating-point types will be interpreted as floating-point types and then involved in the operation.**

**In other words, we can also understand that arithmetic conversion is just special processing done by the compiler, knowing that signed and unsigned operations are converted into unsigned participation, and integer and floating point operations will be converted into floating point operations.**

**Specific analysis of the specific situation, empty talk does not actually make much sense, just understand these functions first.**

## ✍3, operator properties

**There are three factors that influence the evaluation of complex expressions.**

**1. The priority of the operator
2. The associativity of the operator
3. Whether to control the evaluation order.**

**Which of two adjacent operators is executed first?**

**depending on their priority. If both have the same priority, it depends on their associativity.**

**The relevant properties of each operator are shown in the following table:**

operator | describe | Usage example | result type | associative | Whether to control the evaluation order |
---|---|---|---|---|---|

（) | cluster | (expression) | same as expression | N/A | no |

（） | function call | rexp（rexp，…,rexp） | rexp | L-R | no |

[ ] | subscript reference | rexp[rexp] | lexp | L-R | no |

. | access structure members | lexp.member_name | lexp | L-R | no |

-> | access structure pointer member | rexp->member_name | lexp | L-R | no |

++ | suffix auto increment | lexp ++ | rexp | L-R | no |

– | suffix decrement | lexp – | rexp | L-R | no |

! | logical inverse | ! rexp | rexp | R-L | no |

~ | bitwise negation | ~ rexp | rexp | R-L | no |

+ | Monocular, indicating a positive value | + rexp | rexp | R-L | no |

– | Monocular, representing negative values | – rexp | rexp | R-L | no |

++ | Prefix auto increment | ++ lexp | rexp | R-L | no |

– | prefix decrement | – lexp | rexp | R-L | no |

* | indirect access | * rexp | lexp | R-L | no |

& | take address | & lexp | rexp | R-L | no |

sizeof | Take its length, expressed in bytes sizeof reexp | sizeof(type) | rexp | R-L | no |

(type) | type conversion | (type) rexp | rexp | R-L | no |

* | multiplication | rexp * rexp | rexp | L-R | no |

/ | division | rexp / rexp | rexp | L-R | no |

% | Integer remainder | rexp % | rexp | L-R | no |

+ | addition | rexp + rexp | rexp | L-R | no |

– | subtraction | rexp – rexp | rexp | L-R | no |

<< | left shift | rexp << rexp | rexp | L-R | no |

>> | right shift | rexp >> rexp | rexp | L-R | no |

> | more than the | rexp > rexp | rexp | L-R | no |

>= | greater or equal to | rexp >= rexp | rexp | L-R | no |

< | less than | rexp < rexp | rexp | L-R | no |

<= | less than or equal to | rexp <= rexp | rexp | L-R | no |

== | equal | rexp == rexp | rexp | L-R | no |

!= | not equal to | rexp != rexp | rexp | L-R | no |

& | bit and | rexp & rexp | rexp | L-R | no |

^ | bit XOR | rexp ^ rexp | rexp | L-R | no |

| | bit or | rexp| rexp | rexp | L-R | no |

&& | logical and | rexp && rexp | rexp | L-R | Yes |

|| | logical or | rexp || rexp | rexp | L-R | Yes |

? : | conditional operator | rexp ? rexp : rexp | rexp | N/A | Yes |

= | assign | lexp = rexp | rexp | R-L | no |

+= | to add | lexp += rexp | rexp | R-L | no |

-= | minus by | lexp -= rexp | rexp | R-L | no |

*= | multiply by | lexp *= rexp | rexp | R-L | no |

/= | divide by | lexp /= rexp | rexp | R-L | no |

%= | modulo by | lexp %= rexp | rexp | R-L | no |

<<= | move left by | lexp <<= rexp | rexp | R-L | no |

>>= | move right by | lexp >>= rexp | rexp | R-L | no |

&= | with | &= rexp | rexp | R-L | no |

^= | XOR | lexp ^= rexp | rexp | R-L | no |

|= | with… or | lexp | = rexp | rexp | R-L | no |

， | comma | rexp，rexp | rexp | L-R | Yes |

**Operator priority: descending from top to bottom.**

**Xiao Yang reminds here: This table that records the properties of each operator in detail does not need to be recited deliberately, just need to master some common operator usage, and get a general understanding.**

## Epilogue

Friends, when you learned this, you should have a new understanding of the content of the expression evaluation part! 🥳🥳🥳In the follow-up, Xiao Yang will summarize other content for you, and constantly update high-quality content to help everyone and make progress together. Come on, dream catchers! Let’s embrace a better tomorrow together! 🎆🎆🎆