Type Conversions

I l @ ve RuBoard

Type Conversions

Statements and expressions should normally use variables and constants of just one type. If, however, you mix types, C doesn't stop dead in its tracks the way, say, Pascal does. Instead, it uses a set of rules to make type conversions automatically. This can be a convenience, but it can also be a danger, especially if you are mixing types inadvertently. (The lint program, found on many UNIX systems, checks for type " clashes ." Many non-UNIX C compilers report possible type problems if you select a higher error level.) It is a good idea to have at least some knowledge of the type conversion rules.

The basic rules are these:

  1. When appearing in an expression, char and short , both signed and unsigned , are automatically converted to int or, if necessary, to unsigned int . (If short is the same size as int , then unsigned short is larger than int ; in that case, unsigned short is converted to unsigned int .) Under K&R C, but not under ANSI C, float is automatically converted to double . Because they are conversions to larger types, they are called promotions .

  2. In any operation involving two types, both values are converted to the higher ranking of the two types.

  3. The ranking of types, from highest to lowest , is long double , double , float , unsigned long , long , unsigned int , and int . One possible exception is when long and int are the same size, in which case unsigned int outranks long . The short and char types don't appear in this list because they would have been already promoted to int or perhaps unsigned int .

  4. In an assignment statement, the final result of the calculations is converted to the type of the variable being assigned a value. This process can result in promotion, as described in Rule 1, or demotion , in which a value is converted to a lower-ranking type.

  5. When passed as function arguments, char and short are converted to int , and float is converted to double . This automatic promotion can be overridden by function prototyping, as discussed in Chapter 9, "Functions."

Promotion is usually a smooth, uneventful process, but demotion can lead to real trouble. The reason is simple: The lower-ranking type may not be big enough to hold the complete number. A char variable can hold the integer 101 but not the integer 22334 . When floating types are demoted to integer types, they are truncated, or rounded toward zero. That means 23.12 and 23.99 both are truncated to 23 and that -23.5 is truncated to -23 . Listing 5.14 illustrates the working of these rules.

Listing 5.14 The convert.c program.
 /* convert.c -- automatic type conversions */ #include <stdio.h> int main(void) {    char ch;    int i;    float fl;    fl = i = ch = 'A';                  /* line 8  */    printf("ch = %c, i = %d, fl = %2.2f\n", ch, i, fl);    ch = ch + 1;                        /* line 10 */    i = fl + 2 * ch;                    /* line 11 */    fl = 2.0 * ch + i;                  /* line 12 */    printf("ch = %c, i = %d, fl = %2.2f\n", ch, i, fl);    ch = 5212205.17;                    /* line 14 */    printf("Now ch = %c\n", ch);    return 0; } 

Running convert.c produces the following:

 ch = A, i = 65, fl = 65.00 ch = B, i = 197, fl = 329.00 Now ch = - 

On this system, which has an 8-bit char and a 32-bit int , here is what happened :

Lines 8 and 9 : The character 'A' is stored as a 1-byte ASCII value in ch . The integer variable i receives the integer conversion of 'A' , which is 65 stored as 4 bytes. Finally, fl receives the floating conversion of 65 , which is 65.00 . Lines 10 and 13 : The character variable 'A' is converted to the integer 65 , which is then added to the 1 . The resulting 2-byte integer 66 is truncated to 1 byte and stored in ch . When printed using the %c specifier , 66 is interpreted as the ASCII code for 'B' .

Lines 11 and 13 : The value of ch is converted to a 4-byte integer ( 66 ) for the multiplication by 2 . The resulting integer ( 132 ) is converted to floating point in order to be added to fl . The result ( 197.00f ) is converted to int and stored in i . Lines 12 and 13 : The value of ch ( 'B' , or 66 ) is converted to floating point for multiplication by 2.0 . The value of i ( 197 ) is converted to floating point for the addition, and the result ( 329.00 ) is stored in fl . Lines 14 and 15 : Here the example tries a case of demotion, setting ch equal to a rather large number. After truncation takes place, ch winds up with the ASCII code for the hyphen character.

The Cast Operator

You should usually steer clear of automatic type conversions, especially of demotions, but sometimes it is convenient to make conversions, providing you exercise care. The type conversions we've discussed so far are done automatically. However, it is possible for you to demand the precise type conversion that you want. The method for doing this is called a cast and consists of preceding the quantity with the name of the desired type in parentheses. The parentheses and type name together constitute a cast operator . This is the general form of a cast operator:

 (type) 

The actual type desired, such as long , is substituted for the word type .

Consider these two lines, in which mice is an int variable. The second line contains two casts to type int .

 mice = 1.6 + 1.7; mice = (int) 1.6 + (int) 1.7; 

The first example uses automatic conversion. First, 1.6 and 1.7 are added to yield 3.3 . This number is then converted through truncation to the integer 3 to match the int variable. In the second example, 1.6 is converted to an integer ( 1 ) before addition, as is 1.7 , so that mice is assigned the value 1+1 , or 2 . Neither form is intrinsically more correct than the other; you have to consider the context of the programming problem to see which makes more sense.

Normally, you shouldn't mix types; that is why some languages don't allow it, but there are occasions when it is useful. The C philosophy is to avoid putting barriers in your way and to give you the responsibility of not abusing that freedom.

Summary: Operating in C

Here are the operators we have discussed so far:

Assignment Operator:

=

Assigns the value at its right to the variable at its left.

Arithmetic Operators:

+

Adds the value at its right to the value at its left.

-

Subtracts the value at its right from the value at its left.

-

As a unary operator, changes the sign of the value at its right.

>*

Multiplies the value at its right by the value at its left.

/

Divides the value at its left by the value at its right. Answer is truncated if both operands are integers.

%

Yields the remainder when the value at its left is divided by the value to its right (integers only).

++

Adds 1 to the value of the variable to its right (prefix mode) or to the value of the variable to its left (postfix mode).

--

Like ++, but subtracts 1.

Miscellaneous Operators:

sizeof

Yields the size, in bytes, of the operand to its right. The operand can be a type-specifier in parentheses, as in sizeof (float) , or it can be the name of a particular variable, array, and so forth, as in sizeof foo .

(type)

As the cast operator, converts the following value to the type specified by the enclosed keyword(s). For example, (float) 9 converts the integer 9 to the floating-point number 9.0 .

I l @ ve RuBoard


C++ Primer Plus
C Primer Plus (5th Edition)
ISBN: 0672326965
EAN: 2147483647
Year: 2000
Pages: 314
Authors: Stephen Prata

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net