Type Conversion
Computers tend to be more restrictive than C when it comes to
arithmetic. For a computer to perform an arithmetic operation, the operands
must usually be of the same size (the same number of bits) and be stored in the
same way. A computer may be able to add two 16-bit integers directly, but not a
16-bit integer and a 32-bit integer or a 32-bit integer and a 32-bit
floating-point number.
C. on the
other hand, allows the basic types to be mixed in expressions. We can combine integers,
floating-point numbers, and even characters in a single expression. The C
compiler may then have to generate instructions that convert
some
operands to different types so that the hardware will be able to evaluate the
expression. If we add a 16-bit short and a 32-bit int, for example, the
compiler will arrange for the short value to be converted to 32 bits. If we add
an int and a float, the compiler will arrange for the int to be converted to
float format. This conversion is a little more complicated, since int and float
values are stored in different ways.
Because
the compiler handles these conversions automatically, without the programmer's
involvement, they're known as implicit conversions. C also allows
the programmer to perform explicit conversions, using the cast
operator. I'll discuss implicit conversions first, postponing explicit
conversions until later in the section. Unfortunately, the rules for performing
implicit conversions are somewhat complex, primarily because C has so many
different arithmetic types. Implicit conversions are performed in the following
situations:
When the operands in an arithmetic
or logical expression don't have the same type. (C performs what are known as
the usual arithmetic conversions.)
When the type of the expression on
the right side of an assignment doesn't match the type of the variable on the
left side.
When the type of an argument in a
function call doesn't match the type of the corresponding parameter.
When the type of the expression in a
return statement doesn't match the function's return type.
Casting
Although
C's implicit conversions are convenient, we sometimes need a greater degree of
control over type corwersion. For this reason, C provides casts. A cast
expression has the form
( type-name ) expression
type-name
specifies the type to which the expression should be converted.
The
following example shows how to use a cast expression to compute the fractional
part of a float value:
float f, frac_part;
frac_part = f - (int) f;
The
cast expression (int) f represents the result of converting the value of f to
type int. C's usual arithmetic conversions then require that (int) f be converted
back to type float before the subtraction can be performed. The difference
between f and (int) f is the fractional part of f, which was dropped during the
cast.
Cast
expressions enable us to document type conversions that would take place
anyway:
i = (int) f; /* f is converted to int */
They also enable us to overrule the
compiler and force it to do conversions.
Type
Definitions and Portability
Type
definitions are an important tool for writing portable programs. One of the
problems with moving a program from one computer to another is that types may
have different ranges on different machines. If i is an int variable, an
assignment like
i = 100000;
is
fine on a machine with 32-bit integers, but will fail on a machine with 16-bit
integers.
For greater portability, consider using typedef to define new names for integer types.
Suppose that we're writing a program that needs variables
capable of storing product quantities in the range 0-50,000. We could use long
variables for this purpose (since they're guaranteed to be able to hold numbers
up to at least 2,147,483,647), but we'd rather use int variables, since
arithmetic on int values may be faster than operations on long values; also,
int variables may take up less space.
Instead of
using the int type to declare quantity variables, we can define our own
"quantity" type:
typedef
int Quantity;
and
use this type to declare variables:
Quantity
q;
When we
transport the program to a machine with shorter integers, we'll change the
definition of Quantity:
typedef long Quantity;
This technique doesn't solve all our problems,
unfortunately, since changing the definition of Quantity may affect the way
Quantity variables are used. At the very least, calls of printf and scanf that
use Quantity variables will need to be changed, with %d conversion
specifications replaced by %ld.
No comments:
Post a Comment