Abstract LinuxC programming one-stop learning

3.1 Integer Promotion

In an expression, you can use signed or unsigned char, short, and Bit-field characters to make the right value of the int or unsigned int type. If the value range of the original type can be expressed in the int type, the value is promoted to the int type. If the value cannot be expressed, it is promoted to the unsigned int type, which is called Integer Promotion. Integer Promotion only affects the values of the preceding types and does not affect other types. C99 stipulates that Integer Promotion applies to the following situations:

1. If the type of a function parameter is unknown, for example, a function declaration in the Old Style C Style is used, or the function parameter list contains ..., when calling a function, you need to perform Integer Promotion on the corresponding real parameters. In addition, the float Type of the corresponding real parameters must be upgraded to the double type. This rule is called the Default Argument Promotion. We know that the parameter list of printf contains..., except the first parameter, the types of other parameters are unknown, so we are calling printf ("% c ",

'A'), 'A' is actually upgraded to the int type before being passed to printf.

2. type conversion in arithmetic operations. Two operands of the arithmetic type perform arithmetic operations, such as a * B. If the types of the operands on both sides are different, the compiler automatically performs type conversion so that the two sides have the same type before the operation. This is called Usual.

Arithmetic Conversion: one step in the Conversion process is Integer Promotion. Let's take an example to understand this step. The complete rules of Usual Arithmetic Conversion will be explained in detail in the next section.

Unsigned char c1 = 255, c2 = 2;

Int n = c1 + c2;

The process of calculating the expression c1 + c2 is to first promote c1 and c2 to the int type and then add them (the value range of unsigned char is 0 ~ 255, can be expressed with int, so do not need to be upgraded to unsigned int), the value of the entire expression is also int type, the final result is 257. Without this improvement process, c1 + c2 overflows, and the final result should be 1. Obviously, the +-*/% arithmetic operations and ><>==! = Usual Arithmetic Conversion is required for these comparison operations, because the types of the operands on both sides are required to be consistent. In addition, which operations need to be performed by Usual?

What about Arithmetic Conversion? We will make a summary in the next chapter.

3. Single Object operators +,-, and ,-,~ There is only one operand, and the types of the operands on the two sides of the shift operator <,> are inconsistent. Therefore, these operations do not require Usual Arithmetic Conversion, but Integer Promotion is also required. Operator ~ , <,> Is described in the next chapter.

3.2. Usual Arithmetic Conversion

The following describes the rules of Usual Arithmetic Conversion:

1. If the type of one side is long double, convert the other side to long double.

2. Otherwise, if the type of one side is double, convert the other side to double.

3. Otherwise, if the type of one side is float, convert the other side to float.

4. Otherwise, both sides should be Integer types. First, perform Integer Promotion on a and B according to the rules described in the previous section. If the types are still different, continue the conversion. First, it is specified that the Conversion level (Integer Conversion Rank) of char, short, int, long, and long is higher than or equal to each other. The signed and unsigned numbers of the same type have the same Rank, then there are the following conversion rules:

A. if both sides are signed or unsigned, the lower Rank type is converted to a higher Rank type. For example, when unsigned int and unsigned long are used for arithmetic operations, they are converted to unsigned long.

B. otherwise, if one side is an unsigned number and the other side is a signed number, the Rank of the unsigned number is not lower than the Rank of the signed number, then, the signed number is converted to the unsigned type on the other side. For example, when unsigned long and int are used for arithmetic operations, they are converted to unsigned long and long are converted to unsigned long.

C. The rest is that one side is the unsigned number and the other side is the signed number, and the Rank of the unsigned number is lower than the Rank of the signed number. There are two cases. If the value range of the unsigned number type can be overwritten, the unsigned number is converted to the signed type on the other side. For example, on platforms that follow LP64, the unsigned int and long are converted to long during arithmetic operations.

D. Otherwise, that is, the number type of the symbol is insufficient to cover the value range of the unsigned number type. Then, the two sides are converted to the unsigned type with a higher Rank among the two. For example, on platforms that follow ILP32, the unsigned int and long are converted into unsigned long during arithmetic operations.

3.3. type conversion generated by value assignment

If the types on both sides of the equal sign are different during assignment or initialization, the compiler converts the type on the right of the equal sign to the type on the left of the equal sign and then assigns a value. For example, int c = 3.14; the compiler will convert the double type on the right to the int type and then assign it to the variable c. We know that the process of passing a parameter through a function call is equivalent to defining a parameter and initializing it with a real parameter. The process returned by a function is equivalent to defining a temporary variable and initializing it with a return expression, therefore, the type conversion generated by the value assignment also applies to these two cases. For example, if the prototype of a function is int foo (int, int );,

Convert two real parameters of the double type to the int type and assign them to the form parameter. If return 1.2 is returned in the function definition, the return value 1.2 is automatically converted to the int type and then returned. The type conversion that occurs during function call and return is often overlooked because the function prototype and function call are not written together. For example, char c = getchar (); when you see this sentence, it is often assumed that the return value of getchar is of the char type. In fact, the return value of getchar is of the int type, in this way, the value assignment will cause a type conversion. We will explain in detail the issues that need to be paid attention to when using this function.