Exforsys

Home arrow Technical Training arrow C Tutorials

C Expressions - Type Conversions

Page 3 of 3
Author: Exforsys Inc.     Published on: 30th Mar 2006    |   Last Updated on: 22nd Jun 2011

C Programming - Expressions

C Expressions - Type Conversions

Sometimes when expressions are evaluated the type of an operand is converted. These conversions may happen implicitly or explicitly. Implicit conversion is done automatically. For example when the operands to some operators have different types the smaller operand is converted to the larger operand's type. You have already seen several examples of implicit type conversion in the tutorial on operators.

Ads

One thing to note here is that operators that take integers usually perform what is called “integer promotion” - converting smaller integral types such as char and short into int before carrying out the operation. Let us look at an example of integer promotion:

Sample Code
  1.   #include <stdio.h>
  2.    
  3.    void main()
  4.    {
  5.            char a = 100;
  6.            char b = 28;
  7.            int  c;
  8.            char d;
  9.    
  10.           c = a + b;
  11.           d = a + b;
  12.           printf( "c = %d, d = %dn", c, d );
  13.   }
Copyright exforsys.com


c = 128, d = -128
 

The addition operator performs implicit integer promotion. On this environment a char is a signed 8 bit value, which has a range of -128 to 127. On line 10, though both a and b are chars they are converted into int before the addition is done, then the result is assigned to c. On line 11 the same thing happens, but the int result of 128 is converted back into a char, which causes the value to “wrap around” to -128 since a positive 128 is not within the range of a char.

C Expressions - Explicit Type Conversion

With explicit type conversion you can tell the compiler to treat a value as a certain type. The way to do explicit type conversion is with the “casting” operator.

The syntax for explicit type conversion is :

(type-name) expression

For example the expression (char *) ptr + 1 will force the compiler to treat ptr as a char pointer (“cast ptr as a char pointer”) and then add one to it. Looking at the operator precedence table above, you can see that the casting operator (on row 4) has higher precedence than the addition operator, so the cast is done first, then the addition is done.

Casting is done when the normal type conversions will not give you the result you want. This example shows the difference:

Sample Code
  1. #include <stdio.h>
  2.    
  3.    void main()
  4.    {
  5.            int i = 5;
  6.            double d = i / 6;
  7.    
  8.            printf( "d = %fn", d );
  9.    
  10.           d = (double) i / 6;
  11.           printf( "d = %fn", d );
  12.   }
Copyright exforsys.com


The output is:

d = 0.000000 d = 0.833333
 

On line 6, since i and the constant 6 are both integers an integer division is done which gives 0. On line 10 i is cast to a double, which forces the division to be done using double precision floating point values. This gives the result 0.83.

Another way to get the right result on line 10 would have been to not use the cast and instead change the constant 6 to 6.0:

Sample Code
  1. 10         d = i / 6.0;
Copyright exforsys.com


Explicit type conversion is also used to change the compiler's idea of what type a pointer is pointing to. In this next example we use void * which is basically a pointer to any type.

Sample Code
  1. #include <stdio.h>
  2.  
  3.   typedef enum { INT_ARG, CHAR_ARG, DBL_ARG } ArgType;
  4.  
  5.   void printit( ArgType type, void * data )
  6.   {
  7.            switch( type )
  8.            {
  9.              case INT_ARG:
  10.                   printf("data is %dn", *(int *)data );
  11.                   break;
  12.             case CHAR_ARG:
  13.                   printf("data is %cn", *(char *)data );
  14.                   break;
  15.             case DBL_ARG:
  16.                   printf("data is %fn", *(double *)data );
  17.                   break;
  18.           }
  19.   }
  20.  
  21.   void main()
  22.   {
  23.           int i = 20;
  24.           double d = 78.9571;
  25.           char c = 'A';
  26.  
  27.           printit( CHAR_ARG, &c );
  28.           printit( INT_ARG, &i );
  29.           printit( DBL_ARG, &d );
  30.   }
Copyright exforsys.com



The output follows:

data is A
data is 20
data is 78.957100
 

This example uses some features of C you probably have not seen before. On line 3 we define a new type called ArgType that can have one of three values: INT_ARG, CHAR_ARG or DBL_ARG. The switch statement on line 7 works basically like multiple if statements, comparing type to each case value and executing the statements after the case if it is a match.

Ads

The important part for this tutorial is the code in lines 10,13 and 16. The printit() function takes two arguments. The first argument (type) tells what kind of variable the second argument (data) is pointing to. When the printit() function is called data is a pointer to void, which is basically type-less, so it may point to any different type.

However we cannot dereference a void pointer because the compiler does not know what type it is pointing to. On line 10, if type is an INT_ARG data is cast into a pointer to an int which is then de-referenced to get the integer value. On line 13 if type is a CHAR_ARG data is cast into a pointer to char which is de-referenced to get the char value. Line 16 is similar except data is cast into a pointer to a double.



 
This tutorial is part of a C Tutorials tutorial series. Read it from the beginning and learn yourself.

C Tutorials

 

Comments