Is there any difference between type casting & type conversion in c++.
One of the major differences occurs when you work with strings. You cannot say (int)"234" and get the integer 234. Type casting generally only works on primitive numeric data types.
Generally, casting refers to an explicit conversion, whether it's done by C-style cast (T(v)
or (T)v
) or C++-style cast (static_cast
, const_cast
, dynamic_cast
, or reinterpret_cast
). Conversion is generally a more generic term used for any time a variable is converted to another:
std::string s = "foo"; // Conversion from char[] to char* to std::string
int i = 4.3; // Conversion from float to int
float *f = reinterpret_cast<float*>(&i); // (illegal) conversion from int* to float*
Type casting may do a minimum amount of conversion:
signed char Schar; // 1 byte (8 bits) to hold 256 values: -128 to 127
unsigned char Uchar; // 1 byte (8 bits) to hold 256 values: 0 to 255
...
if ( Schar < -10 ) ... // compiler uses SIGNED comparision
Uchar = Schar; // implicit conversion only copies the 8 bits
Uchar = (char) Schar; // explicit conversion may be required by compiler
if ( Uchar > 200 ) ... // compiler uses UNSIGNED comparision
...OR...
if ( (unsigned char) Schar > 200 ) ... // explicit conversion for UNSIGNED comparision
short Sshort; // 2 bytes (16 bits) to hold 65536 values: -32768 to 32767
unsigned short Ushort; // 2 bytes (16 bits) to hold 65536 values: 0 to 65536
...
// when moving 8 bits into 16 bit variables, what to do with other 8 bits ?
Sshort = (signed short) Uchar; // move 8 bits over and use 0s for other 8 bits
Sshort = (signed short) Schar; // same, but use 1s if negative to make Sshort negative
But this might be considered Type Conversion:
float dbl; // 4 bytes to store floating number in IEEE format
long lng; // 4 bytes to store 32 bit integer value in 2's complement format
...
dbl = lng; // convert from 2's comp to IEEE format - all bits change !
dbl = (float) lng; // explicit form
NOTE: int
is usually the same as short
or long
depending on compiler/CPU
NOTE: signed
is usually optional as this is often the default
No conversion takes place when you specify all variables occupy the same memory space:
typedef union MYUNION // all members occupy same space (memory bytes)
{
signed char Schar; // usual default for char
unsigned char Uchar;
signed short Sshort; // usual default for short
unsigned short Ushort;
signed long Slong; // usual default for long
unsigned long Ulong;
float flt;
double dbl;
};
MYUNION myunion;
myunion.Schar = ... // set variable (memory byte) to value
if ( (unsigned char) myunion.Schar > 200 ) ... // unsigned compare works ok
... is same as (also without moving any data around) ...
if ( myunion.Uchar > 200 ) ... // unsigned compare works ok
... myunion.Sshort ... // other 8 bits are UNASSIGNED GARBAGE !
myunion.Sshort = myunion.Schar; // provide all 16 bits from Schar
... myunion.Sshort ... // Sshort of valid now
myunion.dbl = 12345.0;
... myunion.Ulong ... // has weird value from odd IEEE bit format
myunion.Ulong = (unsigned long) myunion.dbl; // do explicit conversion
... myunion.Ulong ... // has CONVERTED 12345 value
NOTE: *(unsigned long*)&dbl
also produces weird values. It does:
a) take address (location of the bits and bytes) of double dbl
b) consider the address as an address of an unsigned long
c) get unsigned long from that location
Of course, there are some real applications of this technique. Examples: parsing a complicated external binary file or on CPUs with 512 bytes of memory, etc.
Type casting means that you take a string of bits and interpret them differently. Type conversion means that you transform a string of bits from a configuration useful in one context to a configuration useful in another.
For example, suppose I write
int x=65;
char c=(char) x;
char* s=(char*) x;
c will now contain the character 'A', because if I reinterpret the decimal number 65 as a character, I get the letter 'A'. s will now be a pointer to a character string residing at memory location 65. This is almost surely a useless thing to do, as I have no idea what is at that memory location.
itoa(x, s, 10);
is a type conversion. That should give me the string "65".
That is, with casts we are still looking at the same memory location. We are just interpreting the data there differently. With conversions we are producing new data that is derived from the old data, but it is not the same as the old data.