Program --- C language details 16 (read the absolute value, compilation type ansi c and K & amp; R c type judgment, C compiler type conversion bug details)
Main Content: compilation type ansi c and K & r c types judgment, c compiler bug details
# Include
Int main () {// Example 1: Compiler type judgment/** K & R adopts the unsigned retention principle, that is, when an unsigned type is used in combination with ing or a smaller integer, The result type is unsigned * ansi c adopts the value retention principle, that is, when several integer operands are mixed like the following, the result type may be signed or unsigned *, the result depends on the relative size of the operand type */if (-1 <(unsigned char) 1) // The Compiler I use is ANSI C, if (-1 <(unsigned int) 1),-1 is converted to a huge positive number, // but the current expression is not converted, confirms the ansi c value retention principle printf ("-1 is less than (unsigned char) 1: ANSI semantics \ n"); elseprintf ("-1 NOT less than (unsigned char) 1: K & R semantics \ n ");/ **************************************** * ************ Example 2: error example ************************************* * **************/int array [] = {1, 2, 3, 4, 5, 6, 7}; # define TOTAL_ELEMENTS (sizeof (array)/sizeof (array [0])/* use array [0] instead of array [int], you can change the array type without changing # define statement (for example, convert int to char) */int d =-1, x;/* (d =-1) <= (7-2 = 5) it is reasonable to print the following statement *, but TOTAL_ELEMENTS returns the unsigned int type (because the type * returned by sizeof () is unsigned ), if statement in sig To test the equality between ned int and unsigned int, * converts the type of d to the unsigned int type, and-1 to the unsigned int type to a large positive integer, * This bug exists in ansi c. In K & r c, sizeof also returns unsigned. You need to fix this problem, add the if (d <= (int) TOTAL_ELEMENTS-2) */if (d <= TOTAL_ELEMENTS-2) {x = array [d + 1]; printf ("x = % d \ n", x);}/* tips: 1. Do not use the unsigned type in your code, especially, do not use the unsigned number only because it does not have a negative value (such as age or national debt). 2. Try to use a signed type like int, in this way, you do not have to worry about the convenience when upgrading complex details of the hybrid type (for example, converting-1 to a very large positive number). 3. Only when bit segments and binary masks are used can you Use an unsigned number. Use forced type conversion in expressions to make the operands unsigned or signed, so that the compiler does not have to select the result type. In the first example, */return 0 ;}
#include
int main ()
{
// Example 1: Compiler type judgment
The
/ *
* K & R adopts the unsigned retention principle, that is, when an unsigned type is mixed with ing or smaller integer types, the result type is unsigned
* ANSI C adopts the value retention principle, that is, when several integer operands are mixed and used as follows, the result type may be signed or unsigned
*, The result depends on the relative size of the operand type
* /
if (-1 <(unsigned char) 1) // I use the compiler is ANSI C, when written as if (-1 <(unsigned int) 1), -1 is converted into a huge positive number,
// The current expression is not converted, which confirms the ANSI C value retention principle
printf ("-1 is less than (unsigned char) 1: ANSI semantics \ n");
else
printf ("-1 NOT less than (unsigned char) 1: K & R semantics \ n");
The
/ ************************************************* ***
* Example 2: Explanation of error example *
************************************************** ** /
int array [] = {1,2,3,4,5,6,7};
#define TOTAL_ELEMENTS (sizeof (array) / sizeof (array [0])) / * Use array [0] instead of array [int], you can change the type of array array without changing the #define statement (such as changing int Into char) * /
int d = -1, x;
The
/ * (d = -1) <= (7-2 = 5) It is reasonable to print the following statement
* But TOTAL_ELEMENTS returns an unsigned int type (because sizeof () returns
* The type is an unsigned number), when the if statement tests equality between signed int and unsigned int,
* Promote the type of d to unsigned int type, convert -1 to unsigned int to a large positive integer,
* This bug exists in ANSI C. In K & R C, sizeof also returns unsigned. To fix this problem, just force the type conversion of TOTAL_ELEMENTS.
* Add if (d <= (int) TOTAL_ELEMENTS-2)
* /
if (d <= TOTAL_ELEMENTS-2)
{
x = array [d + 1];
printf ("x =% d \ n", x);
}
The
/ *
Little inspiration:
1. Try not to use unsigned types in your code. In particular, do n’t use unsigned numbers to represent quantities just because there are no negative values (such as age, national debt)
2. Try to use signed types like int, so that when it comes to upgrading the complex details of mixed types, you do n’t have to worry about convenience (such as -1 is converted into a very large positive number)
3. Unsigned numbers can only be used when bit segments and binary masks are used. Casting should be used in expressions to make the operands unsigned or signed,
In this way, there is no need to have a compiler to select the type of result, as illustrated in the first example
* /
return 0;
}
Output: