Technical Training
C TutorialsTable of Contents
C Programming - Expressions
C Expressions - Evaluation
C Expressions - Type ConversionsC Expressions - Type Conversions
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.
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:
- #include <stdio.h>
- void main()
- {
- char a = 100;
- char b = 28;
- int c;
- char d;
- c = a + b;
- d = a + b;
- printf( "c = %d, d = %dn", c, d );
- }
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:
- #include <stdio.h>
- void main()
- {
- int i = 5;
- double d = i / 6;
- printf( "d = %fn", d );
- d = (double) i / 6;
- printf( "d = %fn", d );
- }
The output is:
d = 0.000000 d = 0.833333On 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:
- 10 d = i / 6.0;
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.
- #include <stdio.h>
- typedef enum { INT_ARG, CHAR_ARG, DBL_ARG } ArgType;
- void printit( ArgType type, void * data )
- {
- switch( type )
- {
- case INT_ARG:
- printf("data is %dn", *(int *)data );
- break;
- case CHAR_ARG:
- printf("data is %cn", *(char *)data );
- break;
- case DBL_ARG:
- printf("data is %fn", *(double *)data );
- break;
- }
- }
- void main()
- {
- int i = 20;
- double d = 78.9571;
- char c = 'A';
- printit( CHAR_ARG, &c );
- printit( INT_ARG, &i );
- printit( DBL_ARG, &d );
- }
The output follows:
data is A data is 20 data is 78.957100This 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.
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.
C Tutorials
- C Programming - An Overview
- C Programming - Data Types : Part 1
- C Programming - Data Types : Part 2
- C Programming - Constants and Identifiers
- C Programming - Operators
- C Programming - Expressions
- C Programming - Managing Input and Output Operations
- C Programming - Decision Making - Branching
- C Programming - Decision Making - Looping
- C Programming - Arrays
- C Programming - Handling of Character String
- C Programming - Functions (Part-I)
- C Programming - Functions (Part-II)
- C Programming - Structures and Unions
- C Programming - Pointers
- C Programming - Dynamic Memory allocation
- C Programming - Linked Lists
- C Doubly Linked Lists
- C Circular Linked Lists
- C Programming - File management in C
- C Language - The Preprocessor
- Call by Value and Call by Reference
- Concept of Pixel in C Graphics
- TSR in C - An Introduction







