Let's take a look at the following program, which is taken from expert C 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 the value of x, because the value assignment statement x = array [d + 1] will not be executed at all. Why? After debugging, it is found that after the program executes the if statement for judgment, it directly skips the execution of the following statement. Next, let's analyze the cause. Because sizeof calculates the return value of the type hour, the return value is of the unsigned int type, and d is of the signed int type. if statements test the two sizes, d will automatically upgrade to the unsigned int type, -1 to unsigned int Is a very large positive integer, so the expression value is always false, so the subsequent value assignment statement will never be executed. This is a type conversion bug. If you do not pay attention to it, it may cause unpredictable consequences for the entire project or project. However, it is difficult to debug this bug directly.
Type conversion in expressions
Implicit conversions include forced conversions and implicit conversions. First, let's take a look at the implicit type conversion rules in traditional C (K & r c:
First, the operands of any char or short int type will be converted to the int type, and any float type will be converted to the double type. If one operand is double, another operand is converted to double, and the calculation result is double. If one operand is long, the other operand is also converted to long, the calculation result is long. If one operand is unsigned, the other operand is also converted to unsigned and the calculation result is unsigned.
Some modifications have been made to the new standard:
1. Integer upgrade: All char, short int, and bit segments are automatically converted to int or unsigned int. If int can represent all values of the source type, convert it to int. Otherwise, convert it to unsigned int.
2. When calculating the value of an expression, the lower type (a data type with a small data range that can be expressed) is usually converted to the higher type before calculation. However, it should be noted that if the expression contains the float type, it may not be converted to the double type before calculation. The following code is provided:
float f1,f2;double d;f1 = d*f2;
If the single-precision calculation is used, and the final result is the same as that of the double-precision calculation, f2 may not be converted. This is different from traditional C, but few compilers (not supported by VC) currently support this.
When an expression contains an unsigned and signed type operand, if one operand is unsigned long int, the other operand is also converted to unsigned long int. If one operand is long int, the other operand is unsigned int. If long int can express the 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, if the other operand is an int, the other operand is converted to an unsigned int.
The following is an example:
Assume that int is 16 bits and long int Is 32 bits.
For-1L <1U, because-1L is signed long int type, while 1U is unsigned int type, because signe long int can fully represent the range of unsigned int, therefore, 1U is converted to signed long int;
For-1L> 1UL, because-1L is signed long int type, and 1UL is unsigned long int type,-1L is converted to unsigned long int.