Typecasting in C and C++
Typecasting is making a variable of one type, such as an int, act like another type, a char, for one single operation. To typecast something, simply put the type of variable you want the actual variable to act as inside parentheses in front of the actual variable. (char)a will make 'a' function as a char.
For example:
#include <iostream>
using namespace std;
int main()
{
cout<< (char)65 <<"\n";
// The (char) is a typecast, telling the computer to interpret the 65 as a
// character, not as a number. It is going to give the character output of
// the equivalent of the number 65 (It should be the letter A for ASCII).
cin.get();
}
One use for typecasting for is when you want to use the ASCII characters. For example, what if you want to create your own chart of all 128 ASCII characters. To do this, you will need to use to typecast to allow you to print out the integer as its character equivalent.
#include <iostream>
using namespace std;
int main()
{
for ( int x = 0; x < 128; x++ ) {
cout<< x <<". "<< (char)x <<" ";
//Note the use of the int version of x to
// output a number and the use of (char) to
// typecast the x into a character
// which outputs the ASCII character that
// corresponds to the current number
}
cin.get();
}
The typecast described above is a C-style cast, C++ supports two other types. First is the function-style cast:
int main()
{
cout<< char ( 65 ) <<"\n";
cin.get();
}
This is more like a function call than a cast as the type to be cast to is like the name of the function and the value to be cast is like the argument to the function. Next is the named cast, of which there are four:
int main()
{
cout<< static_cast<char> ( 65 ) <<"\n";
cin.get();
}
static_cast is similar in function to the other casts described above, but the
name makes it easier to spot and less tempting to use since it tends to be
ugly. Typecasting should be avoided whenever possible. The other three types
of named casts are const_cast, reinterpret_cast, and dynamic_cast. They are of
no use to us at this time.
Typecasts in practice
So when exactly would a typecast come in handy? One use of typecasts
is to force the correct type of mathematical operation to take place. It
turns out that in C and C++ (and other programming languages), the result of
the division of integers is itself treated as an integer: for instance, 3/5
becomes 0! Why? Well, 3/5 is less than 1, and integer division ignores the
remainder.
On the other hand, it turns out that division between floating point numbers,
or even between one floating point number and an integer, is sufficient to
keep the result as a floating point number. So if we were performing some
kind of fancy division where we didn't want truncated values, we'd have to
cast one of the variables to a floating point type. For instance,
static_cast<float>(3)/5
comes out to .6, as you would expect!
When might this come up? It's often reasonable to store two values in
integers. For instance, if you were tracking heart patients, you might
have a function to compute their age in years and the number of heart times
they'd come in for heart pain. One operation you might conceivably want to
perform is to compute the number of times per year of life someone has come in
to see their physician about heart pain. What would this look like?
/* magical function returns the age in years */
int age = getAge();
/* magical function returns the number of visits */
int pain_visits = getVisits();
float visits_per_year = pain_visits / age;
The problem is that when this program is run, visits_per_year will be zero
unless the patient had an awful lot of visits to the doc. The way to get
around this problem is to cast one of the values being divided so it gets
treated as a floating point number, which will cause the compiler to treat the
expression as if it were to result in a floating point number:
float visits_per_year = pain_visits / static_cast<float>(age);
/* or */
float visits_per_year = static_cast<float>(pain_visits) / age;
This would cause the correct values to be stored in visits_per_year. Can you
think of another solution to this problem (in this case)? |