28.การแปลงชนิดข้อมูล(Type conversions)

ในการเขียนโปรแกรมซึ่งมีชนิดข้อมูลอยู่หลายชนิด หากนำมาใช้ร่วมกัน อาจเกิดปัญหาขึ้นได้ทำให้การเก็บข้อมูลสูญหาย ยกตัวอย่างเช่น การส่งค่าระหว่างตัวแปรสองตัวที่มีชนิดข้อมูลต่างกัน ทำให้ช่วยกว้างข้อมูลไม่เท่ากันดังต่อไปนี้

                            thisValue  =  anotherValue;

        หากตัวแปร thisValue เป็นชนิดข้อมูลที่มีช่วงค่ากว้างกว่าตัวแปร anotherValue ก็จะไม่เกิดปัญหา เพราะสามารถเก็บค่าที่ส่งมาได้หมด แต่ถ้าหาก thisValue มีช่วงค่าที่น้อยกว่าเมื่อ anotherValue ส่งค่าที่เกินพื้นที่จัดเก็บของตัวแปร thisValue ก็จะทำให้ข้อมูลสูยหาย ดังนั้น เพื่อไม่ให้เกิดข้อผิดพลาด ภาษา C++ จะแปลงค่าของชนิดข้อมูลที่มีช่วงของค่าน้อยกว่าไปเป็นชนิดข้อมูลที่มีช่วงของค่ามากกว่าก่อน จากนั้นจะแปลงไปเป็นชนิดข้อมูลของตัวแปรที่ทำหน้าที่รับค่า หากตัวแปรนั้นเป็นชนิดข้อมูลมีช่วงของค่ามากกว่าก็เก็บค่าได้หมด แต่หากตัวแปรนั้นเป็นชนิดข้อมูลมีช่วงของค่าน้อยกว่า จะเก็บค่าโดยการตัดส่วนที่เกินออกไป เช่น ชนิดข้อมูล int ใช้ 32 บิตเก็บค่า เมื่อส่งค่าให้ชนิดข้อมูล short ที่ใช้ 16 บิตเก็บค่า ทำให้เก็บค่าได้เฉพาะ 16 บิตแรกเท่านั้น ส่วนที่เหลือก็จะตัดทิ้งไป
        ภาษา C++ ใช้วิธีการดังกล่าว เป็นแบบปิดบัง ซึ่งผู้เขียนสามารถกำหนดให้เป็นแบบเปิดเผยได้เรียกว่า การแปลงชนิดข้อมูล (Type Casting) ซึ่งมี 2 รูปแบบ คือ
                            
                            (typename)value;
                            typename(value);

        นอกจากนี้ภาษา C++ ยังได้เพิ่มตัวดำเนินการแปลงชนิดข้อมูล คือ static_cast, dynamic_cast, const_cast และ reinterpret_cast ซึ่งมีประสิทธิภาพมากขึ้น และสามารถใช้กับชนิดข้อมูลพอยน์เตอร์และคลาสได้


ตัวอย่าง 3.11 TypeCasting.cpp

#include <iostream>
using namespace std ;

int  main ( )  {

      int  myInt = 15 ;
      float  myFloat (17.49) ; 
      char  myChar = 'H' ;

      cout << "Integer value is " << myInt << endl ;
      cout << "Float value is " << myFloat << endl ;
      cout << "Char value is " << myChar << endl ;

      cout << "\nImplicit casting" << endl ;
      cout << "Integer + Float" << myInt+myFloat << endl ;
      cout << "Integer + Char" << myInt+myChar << endl ;
      cout << "Char value is " << myChar << endl ;


      cout << "\nImplicit casting" << endl ;
      cout << "Integer + Float" << myInt+ (int) myFloat << endl ;
      cout << "Integer + Char" << char (myInt) +myChar << endl ;
      cout << "Char + Float" << char (myChar+myFloat) << endl ;

      system( "pause" ) ;
      return 0 ;
}



ผลการรันโปรแกรม

Integer value is 15
Float value is 17.49
Char value is H

Implicit casting
Integer + Float32.49
Integer + Char87
Char + Float89.49

Explicit casting
Integer + Float32
Integer + Char87
Char + FloatY
Press any key to continue . . . _
*******************************************************************************************************

Type conversions

ในบทนี้ คุณจะได้เรียนรู้และเข้าใจเกี่ยวกับการแปลงข้อมูลในภาษา C++ สำหรับแปลงข้อมูลอีกประเภทหนึ่งไปเป็นอีกประเภท ซึ่งการแปลงข้อมูลจะมีอยู่สองแบบใหญ่ๆ คือ Implicit type conversion และ Explicit type conversion และเราจะพูดถึงการแปลงข้อมูลกับข้อมูลประเภท String ที่ใช้ฟังก์ชันจากไลบรารี่ในภาษา C++

Implicit conversion

Implicit conversion เป็นการแปลงข้อมูลมาตรฐานที่จะทำอัตโนมัติเมื่อเราทำการกำหนดค่าให้กับตัวแปร หรือเมื่อตัวแปรหนึ่งถูกคัดลอกไปยังตัวแปรหนึ่ง เราได้เห็นมาแล้วในหลายๆ ตัวอย่างที่ผ่านมา
int a = 10.5;
short b = 4;
float c = a / b;
ในตัวอย่างนี้ เรามี 3 คำสั่ง และแต่ละคำสั่งได้ทีการแปลงข้อมูลแบบ Implicit conversion เราได้สร้างตัวแปร a และ b ในตัวอย่างเราจะได้ a เป็น 10 เพราะว่าตัวแปร a นั้นเป็น Integer ถึงแม้ว่าเราจะได้กำหนดค่า 10.5 ให้มัน แต่คอมไพเลอร์จะทำการแปลงข้อมูลอัตโนมัติ นี้เรียกว่า Implicit conversion
Expression int c = a / b; และตัวแปร c จะมีค่าเป็น 2 เพราะเกิดจาการทำงานของคำสั่ง a / b เนื่องจากตัวแปรทั้งสองทั้ง a และ b มีประเภทเป็น int ถึงแม้ว่าเราจะใช้คำสั่ง short ในการประกาศตัวแปร b แต่มันมีขนาดเล็กกว่า int และทั้งสองประเภทเก็บข้อมูลประเภทเดียวกัน
int a = 5;
int b = 2;
float c = a / b; // 2
float d = a / (float) b; // 2.5
สิ่งหนึ่งที่เกิดขึ้นบ่อยในการเขียนโปรแกรมสำหรับผู้เริ่มต้นคือ การหารตัวเลขจำนวนเต็มด้วยจำนวนเต็ม (int / int) นั้นจะได้ผลลัพธ์เป็น Integer เสมอ ถ้าหากคุณต้องการผลลัพธ์ที่เป็นทศนิยม อย่างน้อยหนึ่งค่าใน Expression ต้องเป็นข้อมูลประเภท Float เหมือนในตัวอย่างในตัวแปร c และ d

Type casting (Explicit type conversion)

ในภาษา C++ เราสามารถแปลงข้อมูลโดยการใช้วิธีที่เรียกว่า Type-casting หรือ Explicit type conversion มันมีสองวิธีในการทำคือแบบ functional และ c-like เราสามารถใช้ได้ทั้งแบบ functional และ c-like ข้อแตกต่างของรูปแบบการใช้งานของมันเป็นดังนี้:
double n = 10.3;
float m = 5.5;
int x = int (n);   // functional
int y = (int) n;   // c-like
ในตัวอย่างนี้ แสดงให้คุณเห็นวิธีการแปลงข้อมูลโดยใช้ทั้งสองวิธี วิธี functional นั้นเป็นการทำงานเหมือนฟังก์ชันโดยจะมีชื่อฟังก์ชันเป็นประเภทข้อมูลที่คุณเห็นเป็น int() และมีอาร์กิวเมนต์เป็นตัวเลขที่เราต้องการแปลง วิธีที่สองคือ c-like เราใช้ประเภทของข้อมูลที่ต้องการแปลงล้อมรอบด้วยวงเล็บ (int) และตามด้วยค่าหรือตัวแปร ตัวอย่างเพิ่มเติม
float a = (float) (10 / 4); // 2
float b = (float) 10 / 4;   // 2.5
float c = 10.0 / 4;   // 2.5
มาพิจารณาตัวอย่างด้านบน คำสั่งแรกจะได้ผลลัพธ์ของ a เป็น 2 เพราะเราทำการหารตัวแปรของ integer สองตัวก่อนที่จะแปลงไปเป็น float ดังนั้นมันจึงได้ค่าเป็น integer อยู่แล้ว ยกเว้นในคำสั่งบรรทัดที่สองและสาม ลำดับความสำคัญของประเภทข้อมูลแบบ float และ double ทำให้การหารระหว่าง 10.0 / 4 เป็นทศนิยมได้
อย่างไรก็ตามการแปลงข้อมูลด้วยวิธี Explicit type conversion นี้สามารถใช้ได้เพียงกับ Primitive data type ที่สามารถแสดงในรูปแบบของตัวเลขได้เท่านั้น เช่น bool char int long``float และ double เป็นต้น

ASCII code table

ต่อไปมาดูตัวอย่างโปรแกรมการแปลงข้อมูลของเรา ซึ่งเป็นโปรแกรมในการแปลง String ในเลขฐานสองไปเป็น Integer และแปลงจาก Integer ไปเป็นเลขฐานสอง และยังแสดงตาราง ASCII
#include <iostream>
#include <cmath>
#include <string>

using namespace std;

string int_to_bin(int);
int bin_to_int(string);

int main()
{
    cout << "Binary / Decimal table" << endl;
    cout << "Number\tint_to_bin\tbin_to_int\tChar" << endl;

    for (int i = 0; i <= 127 ; i++)
    {
        string bin = int_to_bin(i);
        int dec = bin_to_int(bin);
        cout << i << "\t" << bin << "\t" << dec
             << "\t" << (char)i << endl;
    }

    return 0;
}

string int_to_bin(int n)
{
    string bin = "";
    while (n > 0)
    {
        bin = (n % 2 == 0 ? "0" : "1") + bin;
        n /= 2;
    }
    return bin;
}

int bin_to_int(string s)
{
    int len = s.length();
    int dec = 0;
    for (int i = 0; i < len; i++)
    {
        dec += ((int)s[i] - '0') * pow(2, len - i - 1);
    }
    return dec;
}
ในตัวอย่าง เป็นโปรแกรมในการแปลงข้อมูลในตัวเลขฐานสองและฐานสิบ โดยมีฟังก์ชันที่สำคัญอยู่สองฟังก์ชันคือ ฟังก์ชัน int_to_bin() เป็นฟังก์ชันในการแปลงตัวเลขจำนวนเต็มในฐานสิบไปตัวเลขฐาน 2 ในรูปแบบของ String และฟังก์ชัน bin_to_int() นั้นแปลงในทางตรงกันข้าม
string int_to_bin(int n)
{
    string bin = "";
    while (n > 0)
    {
        bin = (n % 2 == 0 ? "0" : "1") + bin;
        n /= 2;
    }
    return bin;
}
นี่เป็นฟังก์ชันในการแปลงจากตัวเลขจำนวนเต็มในฐาน 10 ไปเป็นฐานสอง String เราได้ทำการแปลงโดยการใช้อัลกอรึทึมของการแปลงตัวเลขฐานสอง
int bin_to_int(string s)
{
    int len = s.length();
    int dec = 0;
    for (int i = 0; i < len; i++)
    {
        dec += ((int)s[i] - '0') * pow(2, len - i - 1);
    }
    return dec;
}
และฟังก์ชันนี้เป็นการแปลงจากฐานสอง String ไปเป็นตัวเลข Integer เราได้ทำการวนลูปทุกตำแหน่งของตัวเลขฐานสองและนำเข้าสู่สูตรของการแปลงตัวเลข ยกตัวอย่างเช่นเรามี 111 และจะใช้อัลกอรึมทึมของการแปลงจากฐานสองไปเป็นฐาน 10 ทำให้ได้สูตรเป็น (1 × 22) + (1 × 21) + (1 × 20) นั่นเป็นสิ่งที่โปรแกรมทำ
dec += ((int)s[i] - '0') * pow(2, len - i - 1);
นี่เป็นการทำงานสำหรับสูตรของการแปลงตัวเลข ในคำสั่ง ((int)s[i] - '0') นั้นเป็นการแปลงจาก Char ของตัวอักษร 0 และ 1 ไปเป็น Integer เราเราลบด้วย '0' เพราะว่าค่าของ 0 ใน Integer นั้นมีค่าเท่ากับ 48 คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับ ASCII และฟังก์ชัน pow() เป็นฟังก์ชันในการยกกำลังตัวเลขโดยมีพารามิเตอร์ตัวแรกเป็นฐานของเลขยกกำลัง และตัวที่สองเป็นเลขชี้กำลัง
Binary / Decimal table
Number  int_to_bin      bin_to_int      Char
0               0
1       1       1       ☺
2       10      2       ☻
3       11      3       ♥
4       100     4       ♦
5       101     5       ♣
6       110     6       ♠
7       111     7
8       1000    8
9       1001    9
10      1010    10

11      1011    11      ♂
12      1100    12      ♀
13      1101    13
14      1110    14      ♫
15      1111    15      ☼
16      10000   16      ►
17      10001   17      ◄
18      10010   18      ↕
19      10011   19      ‼
20      10100   20      ¶
21      10101   21      §
22      10110   22      ▬
23      10111   23      ↨
24      11000   24      ↑
25      11001   25      ↓
26      11010   26      →
27      11011   27      ←
28      11100   28      ∟
29      11101   29      ↔
30      11110   30      ▲
31      11111   31      ▼
32      100000  32
...
นี่เป็นผลลัพธ์การทำงานของโปรแกรม ในการแสดงตาราง ASCII ของเรา

*****************************************************************************************************************************************************

สอน C++: การแปลงสตริงให้เป็นตัวเลข เช่น "USD1,230.75" ให้เป็น 1230.75


*****************************************************************************************************************************************************

C++ Type Conversion


In this tutorial, we will learn about the basics of C++ type conversion with the help of examples.

C++ allows us to convert data of one type to that of another. This is known as type conversion.
There are two types of type conversion in C++.
  1. Implicit Conversion
  2. Explicit Conversion (also known as Type Casting)

Implicit Type Conversion

The type conversion that is done automatically done by the compiler is known as implicit type conversion. This type of conversion is also known as automatic conversion.
Let us look at two examples of implicit type conversion.

Example 1: Conversion From int to double

// Working of implicit type-conversion

#include <iostream>
using namespace std;

int main() {
   // assigning an int value to num_int
   int num_int = 9;

   // declaring a double type variable
   double num_double;
 
   // implicit conversion
   // assigning int value to a double variable
   num_double = num_int;

   cout << "num_int = " << num_int << endl;
   cout << "num_double = " << num_double << endl;

   return 0;
}
Output
num_int = 9
num_double = 9
In the program, we have assigned an int data to a double variable.
num_double = num_int;
Here, the int value is automatically converted to double by the compiler before it is assigned to the num_double variable. This is an example of implicit type conversion.

Example 2: Automatic Conversion from double to int

//Working of Implicit type-conversion

#include <iostream>
using namespace std;

int main() {

   int num_int;
   double num_double = 9.99;

   // implicit conversion
   // assigning a double value to an int variable
   num_int = num_double;

   cout << "num_int = " << num_int << endl;
   cout << "num_double = " << num_double << endl;

   return 0;
}
Output
num_int = 9
num_double = 9.99
In the program, we have assigned a double data to an int variable.
num_double = num_int;
Here, the double value is automatically converted to int by the compiler before it is assigned to the num_int variable. This is also an example of implicit type conversion.
Note: Since int cannot have a decimal part, the digits after the decimal point is truncated in the above example.

Data Loss During Conversion (Narrowing Conversion)

As we have seen from the above example, conversion from one data type to another is prone to data loss. This happens when data of a larger type is converted to data of a smaller type.

Data loss in C++ if a larger type of data is converted to a smaller type.
Possible Data Loss During Type Conversion


C++ Explicit Conversion

When the user manually changes data from one type to another, this is known as explicit conversion. This type of conversion is also known as type casting.
There are three major ways in which we can use explicit conversion in C++. They are:
  1. C-style type casting (also known as cast notation)
  2. Function notation (also known as old C++ style type casting)
  3. Type conversion operators

C-style Type Casting

As the name suggests, this type of casting is favored by the C programming language. It is also known as cast notation.
The syntax for this style is:
(data_type)expression;
For example,
// initializing int variable
int num_int = 26;

// declaring double variable
double num_double;

// converting from int to double
num_double = (double)num_int;

Function-style Casting

We can also use the function like notation to cast data from one type to another.
The syntax for this style is:
data_type(expression);
For example,
// initializing int variable
int num_int = 26;

// declaring double variable
double num_double;

// converting from int to double
num_double = double(num_int);

Example 3: Type Casting

#include <iostream>

using namespace std;

int main() {
    // initializing a double variable
    double num_double = 3.56;
    cout << "num_double = " << num_double << endl;

    // C-style conversion from double to int
    int num_int1 = (int)num_double;
    cout << "num_int1   = " << num_int1 << endl;

    // function-style conversion from double to int
    int num_int2 = int(num_double);
    cout << "num_int2   = " << num_int2 << endl;

    return 0;
}
Output
num_double = 3.56
num_int1   = 3
num_int2   = 3
We used both the C style type conversion and the function-style casting for type conversion and displayed the results. Since they perform the same task, both give us the same output.

Type Conversion Operators

Besides these two type castings, C++ also has four operators for type conversion. They are known as type conversion operators. They are:
  • static_cast
  • dynamic_cast
  • const_cast
  • reinterpret_cast
We will learn about these casts in later tutorials.
*********************************************************************************************************************************************

C++ Conversion Operators