First look at the following program, which is excerpted from "C Expert Programming":
#include <stdio.h> int array[] = {23,34,12,17,204,99,16}; #define TOTAL_ELEMENTS (sizeof(array)/sizeof(array[0])) int main(void) { int d=-1,x; /*........*/ if(d <= TOTALTOTAL_ELEMENTS - 2) x = array[d+1]; /*........*/ return 0; }
If there is such a program, you will never know what the value of x is, because of the assignment statement x=array[d+ 1]; will not be executed at all. What's the reason? After debugging, it was found that after the program executes to the if statement for judgment, it directly skips the execution of the next statement. Let’s analyze the reason below, because the return value of sizeof when calculating the type size is unsigned int type, and d is signed int. If the statement tests the size of both, d will automatically be upgraded to unsigned int, and -1 is converted to unsigned int. A large positive integer, so the value of the expression is always false, so the subsequent assignment statement will never be executed. This is a bug caused by type conversion. If you are not careful, it may have unpredictable consequences for the entire project or project. This bug is difficult to debug directly.
Type conversion in expressions
Type conversion includes forced type conversion and implicit conversion. What we are talking about here are implicit conversions. First, let’s understand the rules of implicit type conversion in traditional C (K&R C):
First of all, any char or short int type operand will be converted to int type, and any float type will be converted to double type. If one operand is of type double, then the other operand is also converted to double, and the calculation result is also double; if one operand is of type long, then the other operand is also converted to type long, and the calculation result is also long; if If one operand is unsigned, then the other operand is also converted to unsigned, and the calculation result is unsigned.
However, some modifications have been made in the new standard:
1. Integer upgrade: all char, short int and bit fields will be automatically converted to int or unsigned int first. If int can represent all values of the source type, it is converted to int, otherwise it is converted to unsigned int.
2. When calculating the value of an expression, the low type (data type with a small range of data that can be represented) is usually converted to a high type first, and then participates in the calculation. But one thing to note here is that if there is a float type in the expression, it will not necessarily be converted to a double type before calculation. If there is the following code:
float f1,f2; double d; f1 = d*f2;
If single precision is used for calculation, the final result is the same as double precision calculation, so f2 may not be converted. This is different from traditional C, but currently few compilers (VC does not support it) support this.
When there are unsigned and signed type operands in the expression, if one operand is unsigned long int, then the other operand is also converted to unsigned long int; if one operand is long int, the other The operand is an unsigned int. If long int can express the representation range of unsigned int, the other operand is converted to long int; otherwise both operands are converted to unsigned long int; if one operand is unsigned int and the other operand is int, Then the other operand is converted to unsigned int.
Let’s look at an example:
Suppose int is 16 bits and long int is 32 bits.
So for -1L
For -1L>1UL, because -1L is of type signed long int and 1UL is of type unsigned long int, -1L is converted to unsigned long int.