การคัดเลือกนักแสดงหมายถึงอะไร


18

เมื่อการเข้ารหัสในภาษาระดับต่ำเช่น CI พบว่าบางครั้งการแคสต์หมายถึง 'ตีความไบต์เหล่านี้ซ้ำอีกครั้งราวกับว่ามันเป็นประเภทอื่น' และในบางครั้งในขณะที่ 'แปลงค่านี้ให้เป็นประเภทอื่นอย่างชาญฉลาด'

ความหมายดั้งเดิมของคำคืออะไรและมีความสอดคล้องในการคาดหวังการแปลงและเมื่อใดที่คาดหวังการตีความดิบ?


บทความในWikipediaที่คุณไม่เข้าใจคืออะไร " การแปลงชนิด , Typecastingและการข่มขู่เป็นวิธีที่แตกต่างกันของปริยายหรืออย่างชัดเจนเปลี่ยนนิติบุคคลของชนิดข้อมูลหนึ่งไปยังอีก ... การเขียนโปรแกรมภาษาแต่ละคนมีกฎของตัวเองเกี่ยวกับวิธีการประเภทสามารถแปลง ..."
ริ้น

ความหมายดั้งเดิมของ "to cast" ไม่มีอะไรใน commong กับการเขียนโปรแกรมดูที่นี่merriam-webster.com/dictionary/cast
Doc Brown

1
จำนวนมาก (ส่วนใหญ่มาจากมุมมองของภาษาที่มีการจัดการ) ในบล็อกของ Eric Lippert ในหมวดหมู่ผู้ดำเนินการส่ง
AakashM

1
@gnat: ฉันไม่แน่ใจว่าเป็นคำถามที่จริงจังหรือเป็นเพียงแค่ความพยายามหลอกล่อ แต่ฉันอยากจะรู้วิธีที่จะรู้ว่าคอมไพเลอร์จะทำอะไร: แปลงหล่อหรือบีบบังคับ? กฎของหัวแม่มือคืออะไร?
Alexander Torstling

1
@DocBrown ฉันคิดว่าคำcastในความหมายของคอมพิวเตอร์มีความคล้ายคลึงกับการหล่อในความรู้สึกของโลหะมากขึ้นโดยรูปทรงของโลหะหลอมเหลวจะถูกเปลี่ยนรูปเมื่อเทลงในแม่พิมพ์: britannica.com/EBchecked/topic/377665/metallurgy/81884/
KChaloux

คำตอบ:


10

การคัดเลือกใน C นั้นมีความเป็นเอกลักษณ์ไม่เหมือนภาษาอื่น มันยังไม่ฉลาด

การแคสติ้งใน C แปลงค่าจากประเภทหนึ่งไปเป็นอีกประเภทหนึ่งโดยใช้กฎที่กำหนดอย่างระมัดระวัง หากคุณจำเป็นต้องรู้จริงๆอ่านมาตรฐาน มิฉะนั้นประเด็นหลักคือ:

  1. การแปลงระหว่างประเภทจำนวนเต็มเก็บค่าไว้ถ้าเป็นไปได้ หากปลายทางมีบิตมากกว่านี้จะเป็นการขยายและปลอดภัยโดยทั่วไป แต่อาจเกี่ยวข้องกับส่วนขยายสัญญาณ ถ้าแคบลงบิตจะหายไป
  2. การแปลงระหว่างชนิดของตัวชี้รักษาค่าตัวชี้ไว้ แต่ผลลัพธ์มักไม่ได้กำหนดบ่อยครั้งที่ไม่สามารถพกพาได้และมักจะมีประโยชน์สำหรับสถานการณ์ขั้นสูง
  3. การแปลงระหว่างประเภทจำนวนเต็มและพอยน์เตอร์นั้นตกลงถ้าจำนวนเต็มใหญ่พอและเก็บรักษารูปแบบบิต (สิ่งที่อาจเกิดขึ้นกับค่าเฉลี่ย) หากจำนวนเต็มน้อยเกินไปผลลัพธ์จะไม่ได้กำหนด แต่ไม่มีประโยชน์ ตามกฎ 'ยาว' กว้างพอสำหรับ 'โมฆะ *' แต่ไม่รับประกัน! พอยน์เตอร์ที่สร้างด้วยวิธีนี้อาจไม่ถูกต้องในรูปแบบที่น่าสนใจทุกประเภท
  4. การแปลงระหว่างประเภททศนิยมและจำนวนเต็มเป็นการแปลงเลขคณิตตามที่กำหนดโดยรูทีนไลบรารีที่เหมาะสม (ด้วยการตัดปลายไม่ใช่ปัดเศษ)
  5. คุณสามารถส่งคืนค่าของฟังก์ชันให้เป็นโมฆะ ฉันไม่เคยมี มันไม่ทำอะไรเลย

บาง casts ถูกนำไปใช้โดยปริยายและในบางส่วนของคอมไพเลอร์จะออกคำเตือน ดีที่สุดที่จะฟังคำเตือน!

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

C ++ มีความซับซ้อนมากขึ้น แต่คุณไม่ได้ถามอย่างนั้นใช่ไหม


ฉันสนใจในกฎง่ายๆ แต่ไม่ละเอียดรายละเอียดเล็ก ๆ น้อย ๆ แต่ฉันสนใจในภาษาอื่นที่ไม่ใช่ C ถ้าช่วยให้ชัดเจนขึ้น
Alexander Torstling

2
สิ่งที่ฉันได้รับจากที่นี่เป็นยาสามัญตามที่สมเหตุสมผล ในการเขียนโค้ด C / C ++ ระดับมืออาชีพระดับต่ำรายละเอียดของ miniscule มีความสำคัญ ภาษาส่วนใหญ่ไม่มีปัญหาประเภทนี้ในการแปลงประเภท ขออภัยถ้ามันไม่ช่วยแก้ปัญหาของคุณ
david.pfx

ยกเว้นว่าการแปลงจากT*ไปvoid*และกลับถูกกำหนดไว้อย่างดีเสมอ
Miles Rout

@Miles: ที่จริงแล้วการแปลง T * เป็น U * และหลังใด ๆ จะต้องรักษาค่าตัวชี้เดิม ในคำตอบของฉันฉันแค่พูดว่า 'มักจะไม่ได้กำหนด' เพื่อให้สั้น 'เพราะรายละเอียดบางอย่างยุ่งมาก
david.pfx

1
@supercat: ดู n1570 S6.3.2.3 การแปลง / การปัดเศษระหว่าง T *, U * และ void * จะรักษาค่าตัวชี้ไว้เสมอโดยมีข้อยกเว้นเพียงข้อเดียวเสมอ หาก T * ใด ๆ ที่ไม่ถูกต้องชิดมันก็ไม่ได้กำหนดพฤติกรรม ฉันยอมรับประเด็นของคุณ แต่เพียงเท่านี้
david.pfx

2

ส่วนนี้ของพจนานุกรมเว็บสเตอร์ให้คำจำกัดความที่ถูกต้อง:

a: เพื่อให้รูปร่าง (สาร) โดยการเทในรูปของเหลวหรือพลาสติกลงในแม่พิมพ์และปล่อยให้ชุบแข็งโดยไม่มีแรงกดดัน
b: เพื่อสร้างโดยกระบวนการนี้

ดังนั้นก่อนการร่าย "วัตถุ" ของคุณ (ไม่ใช่ตัวอักษรวัตถุ OOP) อยู่ในรูปร่างที่กำหนด (ชนิด) เมื่อคุณโยนมันอีกครั้งนั่นคือ "เทพื้นคอนกรีต" รอบ ๆ มันเพื่อทำให้เป็นรูปร่างใหม่นั่นคือสิ่งที่คุณทำกับการหล่อ คุณมีตัวเลขเป็นจำนวนเต็มรูปหกเหลี่ยมและหลังจากการร่ายคุณจะได้รับสตริงรูปสี่เหลี่ยมผืนผ้า


2
นอกจากนี้ : "เพื่อกำหนดบทบาทบางอย่างให้กับ (นักแสดง)"
Kelly Thomas

ได้. ฉันแน่ใจว่านี่ดีที่สุด +1
david.pfx

2

มันอาจมีประโยชน์ในการแยก C casts ออกเป็นสองกลุ่ม:

  1. Numeric casts - แปลงตัวเลขระหว่างการแทนค่าหนึ่งไปเป็นอีกการพยายามเก็บค่า ยกตัวอย่างเช่น - จะเป็น(int)3.1 3มีกฎที่แน่นอนที่กำหนดว่าจะเกิดอะไรขึ้นเมื่อไม่สามารถเก็บค่าที่แน่นอนได้

  2. Pointer casts - เก็บที่อยู่หน่วยความจำไว้ แต่เปลี่ยนวิธีการที่ถูกปฏิเสธ ตัวอย่างเช่นสำหรับfloat x=3.5, *(int *)&xจะให้1080033280- 3.5จำนวนเต็มนี้จะถูกแทนด้วยรูปแบบบิตเดียวกันที่แสดงถึงลอย


Keep the memory address, but change the way it's dereferenced.การอ้างอิงตัวชี้ที่พิมพ์ผิดไม่ได้กำหนดไว้ มาตรฐานรับประกันเฉพาะการส่งจาก& A *ถึงB *ด้านหลังจะให้ผลเหมือนกันA *ซึ่งอาจไม่ถูกต้องสำหรับการอ้างถึงในอันดับที่ 1 - หรือถ้าB *เป็นchar *, มันสามารถใช้ในการอ่านการแสดงวัตถุประเภทใดก็ได้ สำหรับประเภทอื่นทั้งหมดB *ตัวชี้การพิจารณาความผิดพลาดนั้นเป็นประเภทการสะกดคำ UB และละเมิดนามแฝงที่เข้มงวด อย่างไรก็ตามแม้ว่าคอมไพเลอร์ไม่ได้ทิ้งตัวอย่างที่ 2 ข้างต้นด้วยเหตุผลนั้นคุณกำลังตั้งสมมติฐานที่ไม่สามารถอธิบายได้เกี่ยวกับรูปแบบบิต
underscore_d

1
cast (v): to receive form in a mold

ใน C ++ ประเภทต่าง ๆ สามารถทำให้ชัดเจนมากขึ้นโดยมีreinterpret_castความหมายว่า "ปฏิบัติกับไบต์เหล่านี้ราวกับว่าพวกเขาเป็นอย่างนี้แล้ว" ใน C คุณสามารถทำให้ชัดเจนโดยใช้ a union, การร่ายกับตัว(type)ดำเนินการจะพยายามรักษาผลลัพธ์ที่เป็นตัวเลขเทียบเท่ากับการสูญเสียความแม่นยำ


2
ในการพอยน์เตอร์แบบ C จะทำการตีความใหม่อยู่เสมอและการคำนวณค่าจะคงไว้ซึ่งค่าที่ดีที่สุดเสมอไป ใน C ++ มีวิธีการพอยน์เตอร์แบบพอยน์เตอร์หลายวิธีซึ่งเป็นสาเหตุที่ทำให้มีชนิดการร่ายที่ชัดเจนยิ่งขึ้น
Jan Hudec

ซีแมนทิกส์นำเสนอตัวชี้ C ไม่จำเป็นต้อง "ตีความใหม่" มันจะถูกต้องตามกฎหมายสำหรับโปรเซสเซอร์ที่ใช้การระบุคำ แต่ต้องการโต้ตอบกับโค้ดแบบไบต์เพื่อให้ได้int*คำนั้นและอีกหนึ่งคำchar*นั้นเป็นสองคำ หล่อ(int*)ไปจะต้องมีการเพิ่มขึ้นของคำพิเศษที่ควรจะเป็นสิ่งที่คุ้มค่าจะระบุไบต์แรกของ(char*) int
supercat
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.