# You know the operator knowledge, but what about expression evaluation

✅Author’s profile: Hello everyone, I’m Xiao Yang
blog🔥 series of columns: Xiao Yang takes you to play with the C language [primary]
🐳 Hope you all support 🥰 and make progress together!****

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.