Type conversions

27 June 2015

ในการเขียนโปรแกรมคอมพิวเตอร์นั้น เราจัดการกับข้อมูลประเภทต่างๆ เช่น ตัวเลขจำนวนเต็ม ตัวเลขจำนวนจริง หรือข้อมูลแบบตัวอักษร ในบางสถานะการณ์เราจำเป็นต้องทำการแปลงข้อมูลเพื่อนำมาใช้ในโปรแกรม ซึ่งในภาษา C นั้นมีการแปลงข้อมูลอยู่สองแบบคือ Implicit conversion และ Explicit conversion หรือ Type casting

Implicit conversion

Implicit conversion เป็นการแปลงข้อมูลของภาษา C ที่คอมไพเลอร์จะทำหน้าที่แปลงให้อัตโนมัติ เช่น การกำหนดค่าให้กับตัวแปร ที่คุณได้เห็นในบทที่ผ่านมา

int a = 10.5;  // 10
short b = 4;  // 4
float c = a / b;  // 2.5

ในตัวอย่าง เราได้ประกาศตัวแปรมา 3 ตัวแปร ตัวแปรแรก a ถึงแม้ว่าเรากำหนดค่าให้กับตัวแปรเป็น 10.5 แต่ เพราะว่าตัวแปร a มีประเภทเป็น integer ซึ่งคอมไพเลอร์จะตรวจสอบและแปลงค่าอัตโนมัติ สำหรับตัวแปร b ถึงแม้ 4 เป็นค่าของ short คอมไพลเลอร์ก็ยังคงตรวจสอบเพื่อที่จะกำหนดค่าให้ตัวแปร b ในตัวแปร c เราได้กำหนดค่าให้กับตัวแปรโดยเป็นค่าของ a/b

Type casting

ในภาษา C เราสามารถแปลงข้อมูลโดยการใช้วิธีการ Explicit conversion หรือ type-casting โดยสามารถทำได้สองแบบคือ แบบ functional และ c-like และเราสามารถได้ทั้งสองวิธี โดยรูปแบบการใช้งานจะต่างกันดังนี้

float a = 8.5;
int x = int (a);  // functional
int y = (int) a;  // c-like

ในตัวอย่างเป็นการแปลงข้อมูลประเภท floating ไปเป็นประเภท integer โดยแบบแรกในคำสั่ง int (a) เป็นการใช้การแปลงแบบ functional และแบบที่สองคำสั่ง (int) a เป็นแบบ c-like เราสามารถใช้วิธีไหนก็ได้ ซึ่งจะได้ผลลัพธ์เหมือนกัน โดยการใช้สองคำสั่งดังกล่าว จะแปลงตัวเลข 8.5 เป็น 8 มาดูตัวอย่างเพิ่มเติม

float m = 3.125;
float n = m - (int) m;   //  0.125
printf("pointing number is %f", n);

ในตัวอย่างเป็นการหาค่าทศนิยมของตัวเลข โดยเราจะใช้ตัวเลขปัจจุบันลบจำนวนเต็มของมัน โดยการใช้ type-casting ได้

Number overflowing

ในการแปลงข้อมูลในภาษา C สิ่งหนึ่งที่คุณควรจะระวังคือการเกิด overflow หรือข้อมูลสูญหาย ซึ่งมันจะเกิดขึ้นหากคุณแปลงตัวเลขจากประเภทข้อมูลที่มีขนาดใหญ่กว่าไปยังประเภทข้อมูลที่มีขนาดเล็กกว่า มาดูตัวอย่างของการเกิด Overflow ในภาษา C

#include <stdio.h>

int main() {

    int a = 1000000;
    short b = (short)a;
    printf("a = %d\n", a);
    printf("b = %d\n", b);

    double c = 1 / 3.0;
    float d = (float)c;
    printf("c = %.16f\n", c);
    printf("d = %.16f\n", d);

    return 0;
}

ในตัวอย่าง เราได้ทำการแปลงข้อมูลจาก int ไปเป็น short ซึ่งข้อมูลประเภท int นั้นสามารถเก็บข้อมูลได้มากกว่า ในขณะที่ short นั้นสามารถเก็บข้อมูลได้เพียง 32,768 ดังนั้นจึงทำให้เกิดการ overflow เมื่อเราแปลงจาก 1,000,000 ไปเก็บไว้ในตัวแปรประเภท short โดยคำนวณได้จาก 1000000 % 32768 = 16960

และสำหรับข้อมูลแบบจำนวนจริงประเภท float และ double เนื่องจากข้อมูลแบบ double นั้นเก็บความละเอียดของทศนิยมได้มากกว่าคือ 16 จำนวนหลังจุด ส่วน float เก็บได้เพียง 8 จำนวน ทำให้การแปลงจาก double ไปเป็น float จึงอาจจะทำให้สูญเสียความละเอียดไป

a = 1000000
b = 16960
c = 0.3333333333333333
d = 0.3333333432674408

นี่เป็นผลลัพธ์การทำงานของโปรแกรม คุณจะเห็นว่าการแปลงจาก int ไปยัง short นั้นเกิดการ overflow ขึ้นทำให้ตัวแปร b มีค่าเป็น 16960 และสำหรับการแปลงจาก double เป็น float นั้นทำให้ตัวแปร d เริ่มสูญเสียความละเอียดหลังจากทศนิยมในตำแหน่งที่ 8 เป็นต้นไป

Convert string to integer in C

ต่อไปเป็นตัวอย่างของโปรแกรมการแปลงข้อมูลจาก String ไปเป็น Integer ซึ่งเป็นฟังก์ชันของการแปลงที่เราจะเขียนขึ้นเอง นอกจากนี้เรายังใช้การแปลงในภาษา C ด้วย โดยฟังก์ชันนั้นจะใช้อาเรย์สองตัวอักษรที่แสดงในรูปแบบของตัวเลขที่ถูกต้อง นี่เป็นโค้ดของโปรแกรม

// Written by marcuscode.com
#include <stdio.h>
#include <string.h>
#include <math.h>

int str_to_int(char a[]) {
    int sum = 0;
    int inv = 1;
    int i = 0;
    int length = strlen(a);
    int p = length;

    // check for negative number
    if (a[0] == '-') {
        --p;
        i = 1;
        inv = -1;
    }

    for (; i < length; i++) {
        double x = ((int)a[i] - '0') * pow(10, --p);
        sum +=  x;
        printf("+%.0lf\n", x); // debug
    }
    return sum * inv;
}

int main() {

    char a[] = "15234";
    char b[] = "-8987612";

    printf("=%d\n\n", str_to_int(a));
    printf("=%d\n", str_to_int(b));
    return 0;
}

ในตัวอย่าง เป็นโค้ดของการแปลงจาก String ไปยังตัวเลข Integer โดยฟังก์ชัน str_to_int() นั้นมีหนึ่งพารามิเตอร์ที่เป็นอาเรย์ของตัวอักษรเพื่อที่แปลง ฟังก์ชันของเราสามารถทำงานได้กับทั้งตัวเลขจำนวนเต็มบวกและจำนวนเต็มลบ เราได้ใช้ไลบรารี่ของภาษา C จาก string.h เพื่อใช้ฟังก์ชัน strlen() ในการหาความยาวของ String และ math.h เพื่อใช้ฟังก์ชัน pow() เป็นฟังก์ชันยกกำลังตัวเลข คุณสามารถดูวิธีคิดได้ในโค้ดตัวอย่าง

+10000
+5000
+200
+30
+4
=15234

+8000000
+900000
+80000
+7000
+600
+10
+2
=-8987612

นี่เป็นผลลัพธ์การทำงานของโปรแกรมที่แสดงขั้นตอนของการได้มาของตัวเลขแต่ละหลัก

ในบทนี้ คุณได้เรียนเกี่ยวกับการแปลงค่าของข้อมูลทั้งแบบ Implicit และ Explicit conversions ซึ่งมันมีประโยชน์ในด้านต่างๆ อีกมากมาย และเรียนรู้การเกิด Overflow ในการแปลงข้อมูลที่มีขนาดใหญ่กว่าไปยังข้อมูลที่มีขนาดเล็กกว่า และเราได้ให้ตัวอย่างของการแปลงจาก String ของตัวเลขไปเป็นตัวเลข

บทความนี้เป็นประโยชน์หรือไม่?Yes·No