[An article to understand mandatory type conversion and implicit type conversion]

Casting and implicit type conversion

Preface:
In the previous chapter, I have a basic understanding of forced type conversion and implicit type conversion. For details, see C language study notes - Detailed explanation of operators. Next, write an article to fully understand and distinguish.

1. Type conversion

1.1. What is type conversion?

Type conversion is basically type casting, or the process of converting from one type to another . In layman's terms, type conversion between data is a common programming and computing technique.

1.2. What causes type conversion?

Generally, there are the following common situations:
(1) When the operation requires the same type of data : When performing mathematical operations, if the data types of the two operands are different, one of the data types must be converted to the other data type first.
(2) When passing parameters to a function : When calling a function, if the parameter type of the function is different from the passed data type, data type conversion is required.
(3) When inputting data from the outside : When reading external data, such as string data read from a file, it needs to be converted into an appropriate data type before it can be used in the program.
(4) When storing and transmitting data : When storing or transmitting, data types may need to be converted to comply with specific storage or transmission requirements.

1.3. Main classification of type conversion

It is mainly divided into two forms:
(1) Explicit type conversion, or forced type conversion :
that is, using the forced type conversion operator to force the data, in which there is no restriction on the range of the data type (large->small Or small -> large, it can be determined by the programmer's needs) , so it is a forced type conversion.
However, it is worth noting that when forced conversion from large-range data to small-range data, data loss may occur , because during the conversion process, small-range data types may not be able to store data of large-range data types, so data will be lost. Truncation is required for storage, thereby losing data accuracy .

(2) Implicit type conversion :
It is an operation rule. It is usually a type conversion handled by the compiler itself in a safe form and will not cause data loss ; it has different expressions in different scenarios. Generally Implicit type conversion can only convert small types into larger data types , and the details will be discussed separately based on the problem.

2. Forced type conversion

Use the () cast operator to force one data type to another data type without any constraints on the range of the data type. But moving from a large range to a small range may result in data loss.
Conversion from small-range data types to large-range data types :

#include <stdio.h>
int main()
{
    
    
	float a = 10.5;
	printf("%f\n", a);//10.500000
	int b = (int)a;//强制类型转换
	printf("%d\n",b);//10
	return 0;
}

Explanation :
According to the above code, first define a floating-point variable a, and then print it out normally as 10.500000; then,
force type conversion of a and assign it to an integer variable b, and finally print b. Compare the two prints. It is found that when the data of variable a is finally printed out in the form of integer data, then this process is explicit type conversion, that is, forced type conversion. It is not difficult to see that the data behind the decimal point is directly discarded through the forced type conversion operator. Then, let’s take a look at the situation of forced conversion from large range to small range:
the conversion situation of large range data type to small range data type :

#include <stdio.h>
int main()
{
    
    
	int a = 300;
	printf("%d\n", a);//300
	//0000 0000 0000 0000 0000 0001 0010 1100  ---- 300 原码、反码、补码相同 
	char b = (char)a;//强制类型转换
	//char : -128 ~ 127 范围,强制类型转换,产生数据截断
	//0010 1100 ----  44 符号位0正数,原码、反码、补码相同
	//以%d格式打印,是以原码打印,仍然为:
	//0010 1100 ----  44 原码、反码、补码相同
	printf("%d\n", b);//44
	return 0;
}

Explanation :
First, define an integer variable a, and then print it normally as: 300; then, cast a to char type and assign it to variable b, and finally print it out as: 44; among them, the 300 binary sequence is: 0000 0000 0000 0000 0000 0001 0010 1100 - The original code, complement code and complement code of the positive number are the same,
but the range of char is only -128~127, so when the small range cannot be stored, the data will be truncated to: 0010 1100 — 44, This results in data loss, causing the printed result to be 44.

Additional note :
Note that assignment operators: +=, -=, *=, /=, %= have the feature of forced type conversion by default.
like:

short a = 1;
sum += a;
则等价于:
short sum = (short)(sum +a);

3. Implicit type conversion

Implicit type conversion, also known as default type conversion, is a conversion from a data type with a smaller storage range to a data type with a larger range.
Implicit type conversion is mainly divided into two categories:
(1), integer promotion
(2), arithmetic conversion

The main conversion rules are as follows :

1. Characters must be converted to integers first (C language stipulates that character type data and integer data can be used interchangeably).
2. Convert short type to int type (both belong to integer type).
3. Float type data is always converted to double type during operation to improve the accuracy of operation (both belong to real type). 4.
Operations between different types in arithmetic operations also follow implicit conversion rules and integer promotion rules. .

Supplementary explanation :
There is generally no conversion between byte, short, and char (all of which are integer types). Once involved in operations, they will be converted to int type by default before performing operations.

3.1. Integration improvement

concept:

C's integer arithmetic operations are always performed with at least the precision of the "default" integer type. To gain precision, characters and shorts in expressions are converted to ordinary types before use. This conversion is called integer promotion.

The meaning of integer promotion:

The integer operation of the expression must be performed in the corresponding arithmetic unit of the CPU . The byte length of the operand of the integer arithmetic unit (ALU) in the CPU is generally the byte length of int, and is also the length of the general-purpose register of the CPU.
Therefore, even if the addition of two char types is performed by the CPU, it is actually converted to the standard length of the integer operand in the CPU. It is difficult for a general-purpose CPU to directly add two 8-bit bytes (although there may be such byte addition instructions in machine instructions). Therefore, various integer values ​​in the expression whose length may be smaller than the length of int must be converted to int or unsigned int before they can be sent to the CPU to perform operations.

That is: when calculating an expression, various integer types smaller than the length of int must first be promoted to the int type. If the int type is not sufficient to represent it, they must be promoted to the unsigned int type, and then the expression operation is performed.
How to improve the shape? It is promoted according to the sign bit
of the data type of the variable .

3.1.1. Integer promotion routine 1
#include <stdio.h>
int main()
{
    
    
	char a = 3;
	//0000 0000 0000 0000 0000 0000 0000 0011---3
	//char:0000 0011---a 数据截断
	char b = 127;
	//0000 0000 0000 0000 0000 0000 0111 1111---127
	//char:0111 1111---b 数据截断
	char c = a + b;
	//整型提升:
	//0000 0000 0000 0000 0000 0000 0000 0011---3---a最高位是0,那么表示正数,然后高位全补0
	//0000 0000 0000 0000 0000 0000 0111 1111---127-b最高位是0,那么表示正数,然后高位全补0
	//0000 0000 0000 0000 0000 0000 1000 0010
	//char截断:1000 0010--c
	//分析:c最高位为1,表示负数,提升后补1
	//发现a和b均是char类型,都没有达到一个int的大小
	//这里就会发生整型提升
	//char截断:1000 0010--c(-126)
	//1111 1111 1111 1111 1111 1111 1000 0010--补码
	//1111 1111 1111 1111 1111 1111 1000 0001--反码
	//1000 0000 0000 0000 0000 0000 0111 1110--原码,以%d格式打印
	printf("%d\n",c);//-126
	return 0;
}
3.1.2. Integer promotion routine 2
#include <stdio.h>
int main()
{
    
    
	char a = 0xb6;
	short b = 0xb600;
	int c = 0xb6000000;
	//a和b,char和short会整型提升,所以提升后会改变
	//c本身就是int型,所以不变
	if (a == 0xb6)
	{
    
    
		printf("a\n");
	}
	if (b == 0xb600)
	{
    
    
		printf("b\n");
	}
	if (c == 0xb6000000)
	{
    
    
		printf("c\n");//c
	}
	return 0;
}
3.1.3. Integer promotion routine 3

Proof: There is implicit type integer promotion

#include <stdio.h>
int main()
{
    
    
	char c = 1;
	printf("%u\n",sizeof(c));//1 --- char
	printf("%u\n",sizeof(+c));//4 --- unsigned int
	printf("%u\n",sizeof(-c));//4 --- unsigned int
	printf("%u\n",sizeof(!c));//4 gcc编译为-4 
	return 0;
}

3.2. Arithmetic conversion

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

long double
double
float
unsigned long int
long int
unsigned int
int

If the type of an operand is ranked lower in the above list, it must first be converted to the type of another operand and then the operation is performed.
Note :
(1) The arithmetic conversion must be reasonable, otherwise there will be potential problems and errors.
(2) Under the conditions of the same type, when it is greater than or equal to the int type, it is an arithmetic conversion, from small to large. (
3) Between different types, such as float floating point number type and int integer operation, if the bytes are the same, it is 4. Then int is converted to a higher-precision implicit arithmetic type to float, and then arithmetic operations are performed.
(4) Arithmetic conversion is limited to the size of the data type. Only types greater than or equal to int are used. Types smaller than it will be promoted to integer types.

3.2.1. Arithmetic conversion routine 1
#include <stdio.h>
int main()
{
    
    
	int a = 4;
	unsigned int b = 2;
	float c = 2.5;
	double result;
	result = a / b * c;
	printf("Result: %lf\n", result);
	return 0;
}
3.2.2. Arithmetic conversion routine 2
#include <stdio.h>
int main()
{
    
    
	int a = 4;
	float f = 4.5f;//f表示为float类型的常量,没有f默认为double类型
	//如果a + f;
	//则相同字节的条件下,int向上转换为float,向精度更高的转换,再相加。
	return 0;
}

4. Summary

a. Forced type conversion: It is display type conversion. The forced conversion range of the data type is not restricted. However, in terms of syntax, forced conversion from a large value to a small value may cause precision loss or overflow problems.
b. Implicit type conversion: divided into integer promotion and arithmetic conversion. Small to large transformation.
(1) Integer promotion: It is the conversion of the same type. When calculating expressions, various integer types (such as short and char) that are smaller than the length of int must first be promoted to int type. If the int type is not enough to represent, they must be promoted. It is an unsigned int type, and then performs the expression operation.
(2) Arithmetic conversion: When it is greater than or equal to the int type, it is an arithmetic conversion. It is a conversion between different types. In the data type of the hierarchical system, it is converted to a type with longer bytes, and the same bytes are converted to a more accurate type. High direction change.

5. Conclusion

Therefore, if the program wants to ensure data security and operation accuracy, it must have a certain grasp of the type conversion involved and the compiler implementation process, so as to avoid serious errors in some data.

Guess you like

Origin blog.csdn.net/m0_69455439/article/details/132664871
Recommended