กลับไปหน้าบทความ

อ่าน 8 นาที

ไม่มีชื่อบทความ

ใน วิทยาการคอมพิวเตอร์ การแปลง ประเภท [ 1 ] [ 2 ] การ แปลง ประเภท [ 1 ] [ 3 ] การ บังคับประเภท [ 3 ] และ การจัดการประเภท [ 4 ] [ 5 ] เป็นวิธีการต่างๆ ในการเปลี่ยน นิพจน์ จาก...

การแปลงประเภท

ในวิทยาการคอมพิวเตอร์การแปลงประเภท[ 1 ] [ 2 ] การ แปลงประเภท[ 1 ] [ 3 ] การบังคับประเภท[ 3 ]และการจัดการประเภท[ 4 ] [ 5 ]เป็นวิธีการต่างๆ ในการเปลี่ยนนิพจน์จากประเภทข้อมูล หนึ่ง ไปเป็นอีกประเภทหนึ่ง ตัวอย่างเช่น การแปลง ค่า จำนวนเต็มเป็นค่าทศนิยมหรือการแสดงเป็นข้อความในรูปแบบสตริงและในทางกลับกัน การแปลงประเภทสามารถใช้ประโยชน์จากคุณสมบัติบางอย่างของลำดับชั้นประเภทหรือการแสดงข้อมูลได้สองแง่มุมที่สำคัญของการแปลงประเภทคือ เกิดขึ้นโดยปริยาย (โดยอัตโนมัติ) หรือโดยชัดแจ้ง [ 1 ] [ 6 ] และการแสดงข้อมูลพื้นฐานถูกแปลงจากรูปแบบหนึ่งไปเป็นอีกรูปแบบหนึ่ง หรือการแสดงที่กำหนดไว้จะ ถูก ตีความใหม่เป็นเพียงการแสดงของประเภทข้อมูลอื่น[ 6 ] [ 7 ]โดยทั่วไปแล้ว ทั้ง ประเภทข้อมูล พื้นฐานและประเภทข้อมูลผสมสามารถแปลงได้

แต่ละภาษาโปรแกรมมีกฎเฉพาะของตนเองเกี่ยวกับการแปลงประเภทข้อมูล ภาษาที่มีการกำหนดประเภทข้อมูลอย่างเข้มงวดมักจะทำการแปลงโดยปริยายเพียงเล็กน้อยและไม่สนับสนุนการตีความใหม่ของข้อมูล ในขณะที่ภาษาที่มีการกำหนดประเภทข้อมูลอย่างหลวมๆจะทำการแปลงโดยปริยายระหว่างประเภทข้อมูลต่างๆ มากมาย ภาษาที่มีการกำหนดประเภทข้อมูลอย่างหลวมๆ มักอนุญาตให้บังคับให้คอมไพเลอร์ตีความข้อมูลรายการหนึ่งๆ ว่ามีรูปแบบการแสดงผลที่แตกต่างกันได้ตามอำเภอใจ ซึ่งอาจเป็นข้อผิดพลาดในการเขียนโปรแกรมที่ไม่ชัดเจน หรือเป็นวิธีการทางเทคนิคเพื่อจัดการกับฮาร์ดแวร์พื้นฐานโดยตรง

ในภาษาโปรแกรมส่วนใหญ่ คำว่า " coercion"ใช้เพื่อบ่งบอกถึง การแปลงประเภทข้อมูล โดยปริยาย ไม่ว่าจะเกิดขึ้นระหว่างการคอมไพล์หรือระหว่างการทำงานตัวอย่างเช่น ในนิพจน์ที่ผสมระหว่างจำนวนเต็มและจำนวนทศนิยม (เช่น 5 + 0.1) คอมไพเลอร์จะแปลงค่าจำนวนเต็มเป็นค่าทศนิยมโดยอัตโนมัติ เพื่อไม่ให้เศษส่วนสูญหาย การแปลงประเภทข้อมูลโดยชัดแจ้งจะระบุได้โดยการเขียนโค้ดเพิ่มเติม (เช่น การเพิ่มตัวระบุประเภทหรือการเรียกใช้รูทีน ในตัว ) หรือโดยการเขียนรูทีนการแปลงเพื่อให้คอมไพเลอร์ใช้เมื่อมิเช่นนั้นจะหยุดทำงานเนื่องจากประเภทข้อมูลไม่ตรงกัน

ใน ภาษาโปรแกรมที่คล้ายกับ ALGOL ส่วนใหญ่ เช่นPascal , Modula-2 , AdaและDelphi การแปลงค่า (conversion ) และการแคสต์ (casting)เป็นแนวคิดที่แตกต่างกันอย่างชัดเจน ในภาษาเหล่านี้การแปลงค่าหมายถึงการเปลี่ยนค่าจากรูปแบบการจัดเก็บข้อมูลประเภทหนึ่งไปยังอีกประเภทหนึ่งโดยปริยายหรือโดยชัดแจ้ง เช่น จำนวนเต็ม 16 บิตเป็นจำนวนเต็ม 32 บิต ความต้องการพื้นที่จัดเก็บอาจเปลี่ยนแปลงไปอันเป็นผลมาจากการแปลงค่า รวมถึงการสูญเสียความแม่นยำหรือการตัดทอนที่อาจเกิดขึ้นได้ในทางกลับกัน คำว่า แคสต์ หมายถึงการเปลี่ยน การตีความรูปแบบบิตที่แสดงค่าจากประเภทหนึ่งไปยังอีกประเภทหนึ่งอย่างชัดเจน ตัวอย่างเช่น บิต 32 บิตที่ต่อเนื่องกันอาจถูกมองว่าเป็นอาร์เรย์ของค่าบูลีน 32 ค่า สตริง 4 ไบต์ จำนวนเต็ม 32 บิตที่ไม่มีเครื่องหมาย หรือค่าทศลอยความแม่นยำเดี่ยวของ IEEE เนื่องจากบิตที่จัดเก็บไว้จะไม่เปลี่ยนแปลง โปรแกรมเมอร์จึงต้องทราบรายละเอียดระดับต่ำ เช่น รูปแบบการแสดงผล ลำดับไบต์ และความต้องการการจัดเรียง เพื่อทำการแคสต์อย่างมีความหมาย

ในกลุ่มภาษา C และALGOL 68คำว่า " cast"โดยทั่วไปหมายถึง การแปลงประเภทข้อมูล อย่างชัดเจน (ตรงข้ามกับการแปลงโดยปริยาย) ซึ่งทำให้เกิดความกำกวมว่านี่เป็นการตีความใหม่ของรูปแบบบิตหรือเป็นการแปลงการแสดงข้อมูลจริงกันแน่ สิ่งสำคัญกว่านั้นคือวิธีการและกฎเกณฑ์มากมายที่ใช้กับประเภทข้อมูล (หรือคลาส) ที่ชี้ไปยังตัวชี้ และวิธีที่คอมไพเลอร์อาจปรับตัวชี้ในกรณีต่างๆ เช่น การสืบทอดวัตถุ (คลาส)

การคัดเลือกนักแสดงอย่างชัดเจนในภาษาต่างๆ

อาดา

Adaมีฟังก์ชันไลบรารีทั่วไปชื่อ Unchecked_Conversion [ 8 ]

ภาษาที่คล้ายกับภาษาซี

การแปลงประเภทโดยปริยาย

การแปลงชนิดข้อมูลโดยปริยาย หรือที่เรียกว่าการบังคับชนิดข้อมูล (coercion)หรือการสลับชนิดข้อมูล (type juggling ) คือการแปลงชนิดข้อมูลโดยอัตโนมัติโดยคอมไพเลอร์ ภาษาโปรแกรม บางภาษาอนุญาตให้คอมไพเลอร์ทำการแปลงชนิดข้อมูลได้ ในขณะที่บางภาษาบังคับให้ต้องทำการแปลงชนิดข้อมูล

ในนิพจน์แบบผสมชนิดข้อมูล ข้อมูลของชนิดย่อย หนึ่งชนิดหรือมากกว่านั้น สามารถแปลงเป็นชนิดหลักได้ตามต้องการในขณะรันไทม์เพื่อให้โปรแกรมทำงานได้อย่างถูกต้อง ตัวอย่างเช่นโค้ดภาษาซี ต่อไปนี้ถูกต้องตามกฎ:

ดับเบิลดี; ลองแอล; อินทิไอ;ถ้า( d > i ) { d = i ; }ถ้า( i > l ) { l = i ; }ถ้า( d == l ) { d *= 2 ; }

แม้ว่าd , lและiจะเป็นชนิดข้อมูลที่แตกต่างกัน แต่ระบบจะแปลงให้เป็นชนิดข้อมูลที่เท่ากันโดยอัตโนมัติทุกครั้งที่มีการเปรียบเทียบหรือการกำหนดค่า พฤติกรรมนี้ควรใช้ด้วยความระมัดระวัง เนื่องจากอาจเกิดผลลัพธ์ที่ไม่พึงประสงค์ได้ ข้อมูลอาจสูญหายเมื่อแปลงค่าจากเลขทศนิยมเป็นจำนวนเต็ม เนื่องจากส่วนที่เป็นเศษส่วนของค่าเลขทศนิยมจะถูกตัดทิ้ง (ปัดเศษเข้าหาศูนย์) ในทางกลับกัน ความแม่นยำอาจสูญหายเมื่อแปลงค่าจากจำนวนเต็มเป็นเลขทศนิยม เนื่องจากชนิดข้อมูลเลขทศนิยมอาจไม่สามารถแสดงค่าที่เป็นไปได้ทั้งหมดของชนิดข้อมูลจำนวนเต็มบางชนิดได้อย่างแม่นยำ ตัวอย่างเช่น อาจเป็น ชนิดข้อมูลความแม่นยำเดี่ยว IEEE 754ซึ่งไม่สามารถแสดงค่าจำนวนเต็ม 16777217 ได้อย่างแม่นยำ ในขณะที่ชนิดข้อมูลจำนวนเต็ม 32 บิตสามารถทำได้ ซึ่งอาจนำไปสู่พฤติกรรมที่ไม่เป็นไปตามที่คาดหวัง ดังแสดงในโค้ดต่อไปนี้:float

#include <stdio.h>int main ( void ) { int my_int = 16777217 ; float my_float = 16777216.0 ; printf ( "จำนวนเต็มคือ: %d \n " , my_int ); printf ( "จำนวนทศนิยมคือ: %f \n " , my_float ); printf ( "ความเท่ากันของทั้งสอง: %d \n " , my_int == my_float ); }

ในคอมไพเลอร์ที่ใช้ความแม่นยำเดี่ยวแบบ IEEE สำหรับตัวเลขทศนิยม และความแม่นยำระดับ 32 บิตขึ้นไปสำหรับตัวเลขจำนวนเต็ม โค้ดนี้จะแสดงผลลัพธ์ที่แปลกประหลาดดังนี้:

ตัวเลขจำนวนเต็มคือ: 16777217 ค่าทศนิยมคือ: 16777216.000000 ความเท่าเทียมกันของพวกเขา: 1

โปรดสังเกตว่า 1 ในบรรทัดสุดท้ายด้านบนแสดงถึงความเท่าเทียมกัน พฤติกรรมที่แปลกประหลาดนี้เกิดจากการแปลงค่าโดยปริยายi_valueเป็น float เมื่อเปรียบเทียบกับค่าf_valueอื่น การแปลงนี้ทำให้สูญเสียความแม่นยำ ซึ่งทำให้ค่าเท่ากันก่อนการเปรียบเทียบ

ประเด็นสำคัญที่ควรทราบ:

  1. floatทำให้intเกิดการตัดทอน กล่าวคือ การลบส่วนที่เป็นเศษส่วนออก
  2. doubleซึ่งfloatทำให้ตัวเลขปัดเศษ
  3. longส่งintผลให้บิตลำดับสูงส่วนเกินถูกทิ้งไป
ประเภทการส่งเสริมการขาย

One special case of implicit type conversion is type promotion, where an object is automatically converted into another data type representing a superset of the original type. Promotions are commonly used with types smaller than the native type of the target platform's arithmetic logic unit (ALU), before arithmetic and logical operations, to make such operations possible, or more efficient if the ALU can work with more than one type. C and C++ perform such promotion for objects of Boolean, character, wide character, enumeration, and short integer types which are promoted to int, and for objects of type float, which are promoted to double. Unlike some other type conversions, promotions never lose precision or modify the value stored in the object.

In Java:

intx=3;doubley=3.5;System.out.println(x+y);// The output will be 6.5

Explicit type conversion

Explicit type conversion, also called type casting, is a type conversion which is explicitly defined within a program (instead of being done automatically according to the rules of the language for implicit type conversion). It is requested by the user in the program.

doublea=3.3;doubleb=3.3;doublec=3.4;intresult=static_cast<int>(a)+static_cast<int>(b)+static_cast<int>(c);// result == 9// if implicit conversion would be used (as with "result = a + b + c"), result would be equal to 10

There are several kinds of explicit conversion.

checked
Before the conversion is performed, a runtime check is done to see if the destination type can hold the source value. If not, an error condition is raised.
unchecked
No check is performed. If the destination type cannot hold the source value, the result is undefined.
bit pattern
The raw bit representation of the source is copied verbatim, and it is re-interpreted according to the destination type. This can also be achieved via aliasing.

In object-oriented programming languages, objects can also be downcast : a reference of a base class is cast to one of its derived classes.

C# and C++

ในC#การแปลงประเภทสามารถทำได้ในลักษณะที่ปลอดภัยหรือไม่ปลอดภัย (เช่น แบบ C) โดยแบบแรกเรียกว่าchecked type cast [ 9 ]

สัตว์สัตว์= แมวตัวใหม่();// ถ้า (animal คือ Bulldog) stat.type(animal) จะเป็น Bulldog มิฉะนั้นจะเกิดข้อยกเว้นBulldog b = ( Bulldog ) animal ;// ถ้า (animal เป็น Bulldog) ให้กำหนด b เป็น (Bulldog)animal มิเช่นนั้นให้กำหนด b เป็น null b = animal as Bulldog ;// ลบการอ้างอิงถึง Cat() และทำเครื่องหมายไว้สำหรับการเก็บขยะanimal = null ;// b == null b = animal as Bulldog ;

ในภาษาC++สามารถสร้างผลลัพธ์ที่คล้ายกันได้โดยใช้ไวยากรณ์การแปลงประเภทแบบ C++

สัตว์* สัตว์= แมวตัวใหม่();// คอมไพล์ได้เฉพาะในกรณีที่ Animal หรือ Bulldog สืบทอดมาจาก Bulldog ตัวอื่น (หรือตัวเดียวกัน) Bulldog * b = static_cast < Bulldog *> ( animal );// ถ้า (animal คือ Bulldog) ให้กำหนด b เป็น (Bulldog*) animal มิเช่นนั้นให้กำหนด b เป็น nullptr และกำหนด b เป็นdynamic_cast < Bulldog *> ( animal )// เหมือนกับข้างบน แต่จะเกิดข้อยกเว้นหากมีการส่งคืนค่า nullptr // กรณีนี้จะไม่พบในโค้ดที่หลีกเลี่ยงการจัดการข้อยกเว้นBulldog & br = static_cast < Bulldog &> ( * animal );// ยกเลิกการจัดสรร animal หลังการใช้งานdelete animal ; animal = nullptr ;// b == nullptr b = dynamic_cast < Bulldog *> ( animal );

หอไอเฟล

ในภาษา Eiffelแนวคิดเรื่องการแปลงประเภทถูกรวมเข้ากับกฎของระบบประเภท กฎการกำหนดค่าระบุว่า การกำหนดค่า เช่นจะถูกต้องก็ต่อเมื่อประเภทของนิพจน์ต้นทาง ( ) เข้ากันได้กับประเภทของเอนทิตีเป้าหมาย ( ) ในกฎนี้ คำว่า เข้ากันได้กับหมายความว่า ประเภทของนิพจน์ต้นทางนั้นสอดคล้องกับหรือแปลงไปเป็นประเภทของเป้าหมาย ความสอดคล้องของประเภทถูกกำหนดโดยกฎสำหรับโพลีมอร์ฟิซึมในการเขียนโปรแกรมเชิงวัตถุตัวอย่างเช่น ในการกำหนดค่าข้างต้น ประเภทของสอดคล้องกับประเภทของถ้าคลาสที่อ้างอิงอยู่ เป็นคลาสที่สืบทอดมาจากคลาสที่อ้างอิงอยู่x := yyxyxyx

สนิม

Rustไม่มีการแปลงประเภทโดยปริยาย (การบังคับแปลง) ระหว่างประเภทพื้นฐานส่วนใหญ่ แต่การแปลงประเภทโดยชัดแจ้ง (การแคสติ้ง) สามารถทำได้โดยใช้asคีย์เวิร์ด[ 10 ]

let x : i32 = 1000 ; println! ( "1000 as a u16 is: {}" , x as u16 );

การยืนยันประเภท

แนวคิดที่เกี่ยวข้องในระบบประเภทคงที่เรียกว่าการยืนยันประเภท (type assertion ) ซึ่งสั่งให้คอมไพเลอร์จัดการกับนิพจน์ของประเภทใดประเภทหนึ่ง โดยไม่คำนึงถึงการอนุมานของตัวมันเอง การยืนยันประเภทอาจปลอดภัย (มีการตรวจสอบในขณะรันไทม์) หรือไม่ปลอดภัย การยืนยันประเภทไม่ได้แปลงค่าจากประเภทข้อมูลหนึ่งไปเป็นอีกประเภทหนึ่ง

ไทป์สคริปต์

ในTypeScriptการยืนยันประเภททำได้โดยใช้asคำหลัก: [ 11 ]

const myCanvas : HTMLCanvasElement = document.getElementById ( " main_canvas " ) as HTMLCanvasElement ;

ในตัวอย่างข้างต้น ฟังก์ชันdocument.getElementByIdถูกประกาศให้คืนค่าเป็น `Int` HTMLElementแต่คุณรู้ว่ามันจะคืนค่าเป็น `Int` เสมอHTMLCanvasElementซึ่งเป็นชนิดย่อยของHTMLElement`Int` ในกรณีนี้ หากไม่ใช่เช่นนั้น โค้ดส่วนถัดไปที่อาศัยพฤติกรรมของฟังก์ชันHTMLCanvasElementจะไม่ทำงานอย่างถูกต้อง เนื่องจากใน TypeScript ไม่มีการตรวจสอบประเภทในขณะรันไทม์

ใน TypeScript ไม่มีวิธีทั่วไปในการตรวจสอบว่าค่าหนึ่งเป็นประเภทใดประเภทหนึ่งในขณะรันไทม์ เนื่องจากไม่มีการรองรับประเภทในขณะรันไทม์ อย่างไรก็ตาม เป็นไปได้ที่จะเขียนฟังก์ชันที่ผู้ใช้กำหนดเองซึ่งจะบอกคอมไพเลอร์ว่าค่าหนึ่งเป็นประเภทใดประเภทหนึ่งหรือไม่ ฟังก์ชันดังกล่าวเรียกว่าtype guardและประกาศด้วยประเภทการส่งคืนเป็น `type` x is Typeโดยที่ `type` xเป็นพารามิเตอร์หรือthis`type` แทนที่ ` booleantype`

วิธีนี้ช่วยให้การตรวจสอบประเภทที่ไม่ปลอดภัยสามารถอยู่ภายในฟังก์ชันตรวจสอบแทนที่จะกระจายอยู่ทั่วโค้ดเบส

ไป

ในGoการยืนยันประเภทสามารถใช้เพื่อเข้าถึงค่าประเภทเฉพาะจากค่าอินเทอร์เฟซได้ การยืนยันประเภทนี้ปลอดภัยหากค่าดังกล่าวไม่ใช่ประเภทเฉพาะ (ในกรณีที่มีค่าส่งคืนเพียงค่าเดียว) หรือส่งคืนค่าศูนย์ (หากใช้ค่าส่งคืนสองค่า) [ 12 ]

t := i .( T )

การตรวจสอบประเภทนี้จะบอกระบบว่าiมีประเภทเป็นTถ้าไม่ใช่ ระบบจะเกิดข้อผิดพลาดร้ายแรง (panic)

การแปลงประเภทข้อมูลโดยปริยายโดยใช้ยูเนียนที่ไม่มีแท็ก

ภาษาโปรแกรมหลายภาษาสนับสนุนประเภทสหภาพ (union types)ซึ่งสามารถเก็บค่าของหลายประเภทได้ สหภาพ ที่ไม่มีแท็ก (untagged unions) มีให้ใช้งานในบางภาษาที่มีการตรวจสอบประเภทแบบหลวมๆ เช่นCและPL/Iรวมถึงภาษา Pascal ดั้งเดิม ด้วย สหภาพเหล่านี้สามารถใช้เพื่อตีความรูปแบบบิตของประเภทหนึ่งให้เป็นค่าของอีกประเภทหนึ่งได้

ปัญหาด้านความปลอดภัย

ในการแฮ็กการแปลงประเภทข้อมูลคือการใช้การแปลงประเภทข้อมูลในทางที่ผิดเพื่อเปลี่ยนประเภทข้อมูลของตัวแปร ชั่วคราวจากที่กำหนดไว้แต่เดิม [ 13 ]ซึ่งเปิดโอกาสให้แฮ็กเกอร์ เนื่องจากในการแปลงประเภทข้อมูล หลังจากที่ตัวแปรถูก "แปลงประเภทข้อมูล" ให้กลายเป็นประเภทข้อมูลที่แตกต่างกัน คอมไพเลอร์จะถือว่าตัวแปรที่ถูกแฮ็กนั้นเป็นประเภทข้อมูลใหม่สำหรับการดำเนินการเฉพาะนั้น[ 14 ]

ดูเพิ่มเติม

สรุปเนื้อหา

ข้อมูลสำคัญจากบทความ

ข้อมูลสำคัญเกี่ยวกับ ไม่มีชื่อบทความ

ใน วิทยาการคอมพิวเตอร์ การแปลง ประเภท [ 1 ] [ 2 ] การ แปลง ประเภท [ 1 ] [ 3 ] การ บังคับประเภท [ 3 ] และ การจัดการประเภท [ 4 ] [ 5 ] เป็นวิธีการต่างๆ ในการเปลี่ยน นิพจน์ จาก...

อาดา

Ada มีฟังก์ชันไลบรารีทั่วไปชื่อ Unchecked_Conversion [ 8 ]

ภาษาที่คล้ายกับภาษาซี

การแปลงชนิดข้อมูลโดยปริยาย หรือที่เรียกว่า การบังคับชนิดข้อมูล (coercion) หรือ การสลับชนิดข้อมูล (type juggling ) คือการแปลงชนิดข้อมูลโดยอัตโนมัติโดย คอมไพเลอร์ ภาษาโปรแกรม บาง ภาษา อนุญาตให้คอมไพเลอร์ทำการแปลงชนิดข้อมูลได้...

C# and C++

ใน C# การแปลงประเภทสามารถทำได้ในลักษณะที่ปลอดภัยหรือไม่ปลอดภัย (เช่น แบบ C) โดยแบบแรกเรียกว่า checked type cast [ 9 ]