C ถูกพิมพ์อย่างรุนแรงหรือไม่?


88

หากต้องการอ้างอิงWikipedia :

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

มีคำตอบที่ชัดเจนกว่านี้หรือไม่?


190
สำหรับโปรแกรมเมอร์ C การพิมพ์แรงหมายถึงการกดปุ่มให้หนักขึ้น
Dan Dyer

2
C อยู่ด้านที่อ่อนแอในการพิมพ์ต่อเนื่อง แต่มีรายการเพียงพอที่คุณสามารถโต้แย้งได้ทั้งสองด้าน ในขณะที่คุณกำลังทำอยู่คุณอาจถาม (vi หรือ emacs, netbeans หรือ eclipse ฯลฯ )
Cervo

4
สถานะการเล่นบน Wikipedia ไม่ดีพอที่ฉันรู้สึกว่าต้องแก้ไขหน้า Wikipedia หลายหน้า บางทีสิ่งต่างๆอาจจะดีขึ้นเล็กน้อยในตอนนี้ อาจจะ.
Norman Ramsey

40
Re: ข้อคิดเห็นของ Dan (เพื่อให้เครดิตเมื่อถึงกำหนด) หนังสือ "Expert C Programming" ของ Peter van der Linden มีบรรทัดต่อไปนี้: "จนถึงทุกวันนี้โปรแกรมเมอร์ C หลายคนเชื่อว่า 'การพิมพ์ที่หนักแน่นหมายถึงการทุบแป้นพิมพ์ให้หนักขึ้นเป็นพิเศษ"
Alexandros Gezerlis

คำถามดีมาก !!!
Destructor

คำตอบ:


154

"พิมพ์ผิด" และ "พิมพ์ผิด" เป็นคำที่ไม่มีความหมายทางเทคนิคที่ตกลงกันอย่างกว้างขวาง คำศัพท์ที่มีความหมายชัดเจนคือ

  • การพิมพ์แบบไดนามิกหมายความว่าประเภทต่างๆจะแนบกับค่าในขณะรันไทม์และการพยายามผสมค่าของประเภทต่างๆอาจทำให้เกิด "ข้อผิดพลาดประเภทรันไทม์" ตัวอย่างเช่นหากใน Scheme คุณพยายามเพิ่มหนึ่งใน true โดยการเขียน(+ 1 #t)สิ่งนี้จะทำให้เกิดข้อผิดพลาด คุณจะพบข้อผิดพลาดก็ต่อเมื่อคุณพยายามรันโค้ดที่ละเมิด

  • พิมพ์แบบคงที่หมายความว่าประเภทจะถูกตรวจสอบในเวลาคอมไพล์และโปรแกรมที่ไม่มีประเภทคงที่จะถูกปฏิเสธโดยคอมไพลเลอร์ ตัวอย่างเช่นหากใน ML คุณพยายามเพิ่มหนึ่งใน true โดยการเขียน1 + trueโปรแกรมจะถูกปฏิเสธด้วยข้อความแสดงข้อผิดพลาด (อาจเป็นความลับ) คุณมักจะได้รับข้อผิดพลาดแม้ว่ารหัสอาจไม่ถูกเรียกใช้งานก็ตาม

แต่ละคนชอบระบบที่แตกต่างกันตามส่วนหนึ่ง ๆ ว่าพวกเขาให้ความสำคัญกับความยืดหยุ่นมากเพียงใดและพวกเขากังวลเกี่ยวกับข้อผิดพลาดในเวลาทำงาน

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

ไม่มีคำศัพท์เหล่านี้เชื่อมโยงกับจำนวนการแปลงโดยนัยที่มีอยู่ในภาษาใด ๆ

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

ฉันได้เขียนเพิ่มเติมเกี่ยวกับแบบคงที่และแบบไดนามิกที่ว่าทำไมตีความ-Langs-เป็นส่วนใหญ่-ducktyped ขณะที่รวบรวมมีแข็งแกร่งพิมพ์


2
คุณได้คำจำกัดความที่คุณแนะนำสำหรับการพิมพ์ที่แข็งแกร่ง / อ่อนแอ (สิ่งที่เป็นช่องโหว่) มาจากไหน?
Sydius

2
เหตุใดคุณจึงต้องมี "ช่องโหว่" ในสภาพแวดล้อมการพิมพ์แบบไดนามิก
Chris Conway

4
@Sydius: จากการใช้เวลาส่วนใหญ่ในช่วง 20 ปีที่ผ่านมากับคนที่ออกแบบสร้างและวิเคราะห์ภาษาโปรแกรมและระบบประเภท นั่นคืองานที่ได้รับค่าตอบแทนของฉัน :-)
Norman Ramsey

@ คริส: ฉันไม่เคยเห็นภาษาพิมพ์แบบไดนามิกที่มี 'ช่องโหว่' การใช้ช่องโหว่โดยทั่วไปคือการทำงานร่วมกับระบบรันไทม์หรือ OS เช่นใช้ที่อยู่ดิบและแปลงเป็นตัวชี้เป็นค่าภาษาที่มีพฤติกรรมดี คุณสามารถทำได้ในการตั้งค่าแบบไดนามิก แต่ฉันไม่ทราบความพยายามใด ๆ
Norman Ramsey

1
@NormanRamsey ฉันคิดว่าคริสอ้างถึงคำถามของเขากับ:whereas "weakly typed" means "there are loopholes in the type system
Nir Alfasi

23

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

แต่มีจุดอ่อนเล็กน้อย จุดอ่อนที่สำคัญอย่างหนึ่งคือไทเทคาสต์ - โดยพื้นฐานแล้วจะบอกว่าคุณกำลังยุ่งอยู่กับประเภทของวัตถุและคอมไพเลอร์ควรเงียบ (เมื่อทำได้) void*ยังเป็นจุดอ่อนอีกประการหนึ่ง - เป็นตัวชี้ทั่วไปสำหรับประเภทที่ไม่รู้จักและเมื่อคุณใช้พวกเขาคุณต้องระมัดระวังเป็นพิเศษว่าคุณกำลังทำในสิ่งที่ถูกต้อง คอมไพเลอร์ไม่สามารถตรวจสอบการใช้งานส่วนใหญ่ของvoid*ไฟล์. void*ยังสามารถแปลงเป็นตัวชี้เป็นประเภทใดก็ได้โดยไม่ต้องร่าย (เฉพาะใน C ไม่ใช่ C ++) ซึ่งเป็นจุดอ่อนอีกประการหนึ่ง


คำตอบที่ดีแม้ว่า "ตัวพิมพ์ ... และคอมไพเลอร์ควรจะเงียบ" รบกวนฉัน ตัวพิมพ์ไม่เหมือนกับการปิดคำเตือน แต่จะเปลี่ยนการตีความค่าที่อ้างถึง
เจฟฟ์สูง

15
คุณกำลังสับสนระหว่างการพิมพ์แบบ "คงที่" และ "แรง" สองแนวคิดนี้เป็นอิสระจากกัน
bendin

1
Dennis Richie (ผู้เขียน C) เรียก C ว่า 'พิมพ์อย่างรุนแรงและตรวจสอบอย่างอ่อน'
TimZaman

11

วรรณกรรมไม่ชัดเจนเกี่ยวกับเรื่องนี้ ฉันคิดว่าการพิมพ์ผิดอย่างแรงนั้นไม่ใช่ใช่ / ไม่ใช่มีระดับการพิมพ์ที่รุนแรงแตกต่างกัน

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

ดังนั้น:

ภาษาที่ระบุสิ่งที่เกิดขึ้นที่รันไทม์ในทุกกรณี (เช่นการเพิ่มตัวเลขลงในสตริง) เรียกว่าพิมพ์แบบไดนามิก ภาษาที่ป้องกันการรันโปรแกรมที่มีข้อผิดพลาดในขณะคอมไพล์จะพิมพ์แบบคงที่ ภาษาที่ไม่ระบุสิ่งที่เกิดขึ้นและไม่มีระบบประเภทเพื่อป้องกันข้อผิดพลาดเรียกว่าพิมพ์ผิด

Java ถูกพิมพ์แบบคงที่หรือไม่? ใช่เนื่องจากระบบประเภทไม่อนุญาตให้ลบสตริงออกจากตัวเลข ไม่เพราะมันช่วยให้คุณหารด้วยศูนย์ คุณสามารถป้องกันการหารด้วยศูนย์ในเวลาคอมไพล์ด้วยระบบชนิด ตัวอย่างเช่นการสร้างประเภทตัวเลขที่ไม่สามารถเป็นศูนย์ (เช่น NonZeroInt) และอนุญาตให้หารด้วยตัวเลขที่มีประเภทนี้เท่านั้น

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


ฉันชอบการจัดแนวไดนามิกและคงที่ของคุณเป็นรูปแบบที่แข็งแกร่งและอ่อนแอ อย่างไรก็ตามฉันไม่แน่ใจว่าฉันเข้าใจประเด็นของคุณเกี่ยวกับระบบที่พิมพ์แบบคงที่หยุดหารด้วยศูนย์ หากการพิมพ์แบบคงที่ของฉันintได้รับค่าจากอาร์กิวเมนต์ของผู้ใช้หรือบรรทัดคำสั่งหรือไฟล์ไม่มีอะไรที่คอมไพเลอร์สามารถทำได้เพื่อหยุดการเป็นศูนย์!
Rikki

1
มีระบบประเภทสแตติกที่ป้องกันสิ่งนี้ แต่ภาษาส่วนใหญ่อาจ "พิมพ์" แบบอ่อนหรือแบบไดนามิกเมื่อเทียบกับการหารด้วยศูนย์เนื่องจากเป็นพฤติกรรมที่ไม่ได้กำหนด (C) หรือมีข้อยกเว้น (Java)
Jules

11

C ถือว่าพิมพ์ผิดเล็กน้อยเนื่องจากคุณสามารถแปลงประเภทใดก็ได้เป็นประเภทอื่นผ่านการแคสต์โดยไม่มีข้อผิดพลาดของคอมไพเลอร์ คุณสามารถอ่านเพิ่มเติมเกี่ยวกับปัญหาที่นี่


2
วิกิพีเดียทำให้เข้าใจผิดที่นี่ C ถูกพิมพ์อย่างรุนแรงประเภทมีความถูกต้องมากและคอมไพเลอร์จะ จำกัด หากคุณทำผิดอย่างไรก็ตาม C ยังมีคุณสมบัติให้คุณข้ามสิ่งนี้ เปรียบเทียบกับภาษาเช่น BCPL ที่มีเฉพาะประเภท 'ไบต์'
gbjbaanb

13
พิมพ์ผิดไม่ได้หมายความว่าภาษาไม่มีประเภทใด ๆ แต่หมายความว่าประเภทสามารถบังคับโดยปริยายจากประเภทหนึ่งไปยังอีกประเภทหนึ่งได้ เปรียบเทียบกับ Python ซึ่งเป็นภาษาที่พิมพ์อย่างชัดเจนซึ่งคุณต้องแปลงประเภทอย่างชัดเจนด้วยการเรียกใช้ฟังก์ชัน
mipadi

ความสามารถในการร่าย C ยังมีส่วนทำให้มันเป็นคนอ่อนแอด้วย ?? ฉันมีข้อสงสัยเช่นนี้ตลอดไป
Suraj Jain

8

C พิมพ์แรงกว่า Javascript และพิมพ์น้อยกว่า Ada

ฉันจะบอกว่ามันตกอยู่ในด้านที่พิมพ์อย่างรุนแรงของความต่อเนื่อง แต่อาจมีคนไม่เห็นด้วย (แม้ว่าจะผิดก็ตาม)

สรุปได้อย่างไร?


มันเป็นคำตอบแบบลิ้นปี่ แต่จงทำความผิดอย่างละเอียด
Michael Burr

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

5
ดังที่คำตอบที่ดีของ Norm Ramsey ระบุว่า "พิมพ์หนักแน่น" และ "พิมพ์ผิด" ไม่ใช่คำที่กำหนดไว้อย่างชัดเจน นอกจากนี้ตราบใดที่ Javascript ถูกพิมพ์อย่างรุนแรงบางคนอาจเชื่อว่า ("4" / ​​"2") เป็นนิพจน์ Javascript ที่ถูกต้องอาจบ่งชี้เป็นอย่างอื่น
Michael Burr

5

C ถือว่าพิมพ์แบบคงที่ (คุณไม่สามารถเปลี่ยนตัวแปรจาก int เป็น float ได้) เมื่อประกาศตัวแปรแล้วมันจะติดอยู่อย่างนั้น

แต่ถือว่าพิมพ์ผิดเล็กน้อยเนื่องจากประเภทต่างๆสามารถพลิกพลิกได้

0 คืออะไร? '\ 0', FALSE, 0.0 ฯลฯ ..

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

โดยพื้นฐานแล้ว c มีประเภทข้อมูลหลักสองประเภท ได้แก่ จำนวนเต็มและตัวเลขทศนิยม บูลีนอื่น ๆ อย่างอื่น enums (ไม่ง่าย แต่เหมาะสม) ฯลฯ ถูกนำมาใช้เป็นหนึ่งในนั้น แม้แต่อักขระก็เป็นจำนวนเต็ม

เปรียบเทียบกับภาษาอื่น ๆ ที่มีประเภทสตริงประเภท enum ที่สามารถกำหนดให้กับค่าที่กำหนดเท่านั้นประเภทบูลีนที่สามารถใช้ได้เฉพาะนิพจน์ที่สร้างบูลีนหรือจริง / เท็จเท่านั้น

แต่คุณสามารถโต้แย้งว่าเมื่อเทียบกับ Perl C นั้นมีการพิมพ์อย่างรุนแรง ดังนั้นจึงเป็นหนึ่งในข้อโต้แย้งที่มีชื่อเสียงเหล่านั้น (vi vs emacs, linux vs windows ฯลฯ ) C # พิมพ์แรงกว่า C โดยทั่วไปคุณสามารถโต้แย้งไม่ว่าจะด้วยวิธีใดก็ได้ และคำตอบของคุณอาจเป็นไปได้ทั้งสองทาง :) นอกจากนี้หนังสือเรียน / หน้าเว็บบางหน้าจะบอกว่า C พิมพ์ผิดและบางหน้าก็บอกว่า C พิมพ์แรงเกินไป หากคุณไปที่วิกิพีเดียรายการ C จะระบุว่า "พิมพ์อ่อนบางส่วน" ฉันจะบอกว่าเมื่อเทียบกับ Python C นั้นพิมพ์ผิด ดังนั้น Python / C #, C, Perl บนความต่อเนื่อง


โปรดอธิบายเหตุผลของคุณว่า Perl พิมพ์น้อยกว่า C.
user51568

พิมพ์ "การทดสอบ" + 0 # perl จะทำ 0; $ var = "สตริง"; $ var = 1; $ var = 123.4; เป็นตัวแปรชนิดใด
Cervo

ใน C char * test = "การทดสอบ"; printf (การทดสอบ + 0); จะยังคงเป็นสตริงเพียงแค่ใน C ดัชนีจะเปลี่ยนถ้าแทนที่จะเป็นศูนย์ฉันใช้ตัวเลข มันยังค่อนข้างอ่อนแอ แต่แข็งแกร่งขึ้นเล็กน้อยแล้ว perl การทดสอบถ่าน * ทดสอบ = 0; ทดสอบ = 123.4; test = "c"; ... คอมไพเลอร์ของฉันสร้างข้อผิดพลาด
Cervo

ข้อผิดพลาดแจ้งว่าต้องมีการแคสต์ ถึงกระนั้นมันก็ค่อนข้างแข็งแกร่งกว่าการตรวจสอบประเภท Perl เล็กน้อยดังนั้นในความต่อเนื่องฉันต้องบอกว่า C พิมพ์แรงกว่า Perl คุณยังสามารถไปทดสอบ = (ถ่าน *) แล้วใช้ 0, 123.4, 'C' ฯลฯ ได้ แต่มันเป็นข้อผิดพลาดที่จะทำ
Cervo

4

คำตอบดีๆมากมายที่นี่ ฉันต้องการนำเสนอประเด็นสำคัญจากReal World Haskell :

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

(ตัด)

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

ดังนั้นให้ดูคำตอบเกี่ยวกับ C และ C ++ แต่จำไว้ว่า "แข็งแกร่ง" และ "อ่อนแอ" ไม่ได้จับคู่กับ "ดี" และ "ไม่ดี"


4

ตามที่ Dennis Ritchie ( ผู้สร้าง C ) และ Brian Kernighan ระบุว่า C ไม่ใช่ภาษาที่พิมพ์ยาก บรรทัดต่อไปนี้มาจากหนังสือการเขียนโปรแกรมภาษาซีหน้า 3 ย่อหน้าที่ 5

C ไม่ใช่ภาษาที่พิมพ์ยาก แต่เมื่อมีการพัฒนาขึ้นการตรวจสอบประเภทจึงได้รับการปรับปรุง


3

ในความคิดของฉัน C / C ++ ถูกพิมพ์อย่างรุนแรง ประเภทของการแฮ็กที่อนุญาตให้มีการแปลงประเภท (โมฆะ *) อยู่ที่นั่นเนื่องจากความใกล้ชิดของ C กับเครื่อง กล่าวอีกนัยหนึ่งคุณสามารถเรียกคำสั่งแอสเซมเบลอร์จากภาษาปาสคาลและจัดการกับพอยน์เตอร์ได้และภาษาปาสคาลยังถือว่าเป็นภาษาที่พิมพ์มาก คุณสามารถเรียกแอสเซมเบลอร์และ C ไฟล์ปฏิบัติการจาก Java ผ่าน JNI ได้ แต่จะไม่ทำให้ Java พิมพ์ผิด

C เพียงแค่มีแอสเซมเบลอร์ "ฝัง" ไว้ด้วยตัวชี้ดิบและอื่น ๆ


3

คำที่พิมพ์อย่างรุนแรงไม่มีคำจำกัดความที่ตกลงกัน ดังนั้นเว้นแต่คุณจะกำหนดสิ่งที่คุณหมายถึงโดย "พิมพ์ผิด" ก็เป็นไปไม่ได้ที่จะตอบคำถามของคุณ

จากประสบการณ์ของฉันจะใช้คำว่า "พิมพ์ผิด" และ "พิมพ์ผิด" เท่านั้นโดย trolls เพราะพวกเขาขาดคำจำกัดความช่วยโทรลล์ที่จะกำหนดให้พวกเขากลางโต้แย้งเพื่อให้เหมาะกับวาระการประชุมของพวกเขา นอกเหนือจากการเริ่มต้นฟลามิววาร์แล้วคำศัพท์เหล่านี้ไม่มีประโยชน์มากนัก

คุณอาจต้องการดูที่ประเด็นสำคัญของภาษาที่พิมพ์ผิดคืออะไร? ที่นี่บน StackOverflow


3
ฉันไม่เห็นด้วย. "พิมพ์อย่างหนักแน่น" หมายความว่าสามารถกำหนดประเภทข้อมูลของค่าได้และอนุญาตให้ใช้เฉพาะการดำเนินการที่เหมาะสมกับประเภทนั้นเท่านั้น ที่อยู่ "แบบไดนามิก" และ "คงที่" เมื่อสามารถกำหนดได้
joel.neely

2
คุณทำตระหนักประชดของการพยายามที่จะพิสูจน์ยืนยันว่าไม่มีการตกลงกันนิยามโดยการแนะนำเลยความหมายอื่นที่เหมาะสมหรือไม่
Jörg W Mittag

1
@Jorg: ไม่ได้พยายามแนะนำอันอื่น เพียงแค่ระบุสิ่งที่ใช้กันทั่วไปในแวดวงที่ฉันเคลื่อนไหว
joel.neely

1

มีความต่อเนื่องที่มีช่องทางคู่ขนานกันระหว่าง "พิมพ์ผิด" และ "พิมพ์มาก" ซึ่งมีสองคำที่ไม่ได้กำหนดไว้อย่างชัดเจน

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

ภาษาที่พิมพ์แบบไดนามิกอาจยังคงถูกพิมพ์อย่างรุนแรงหากแต่ละอ็อบเจ็กต์มีประเภทเฉพาะ แต่ไม่มีทางที่คอมไพลเลอร์จะทราบประเภทนั้น


0

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


ส่วนใหญ่เป็นความอยากรู้อยากเห็น แต่ฉันกำลังสมัครตำแหน่ง C และอยากรู้ในกรณีที่พวกเขาถามฉันเกี่ยวกับเรื่องนี้
Sydius

จากนั้นอาจเป็นคำตอบที่ยาวกว่าซึ่งให้ความแตกต่างของสิ่งที่ "พิมพ์อย่างหนักแน่น" เป็นแนวทางที่ดีที่สุดแทนที่จะพูดว่า "ใช่" หรือ "ไม่ใช่"
BobbyShaftoe

0

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


มี def อย่างเป็นทางการ สำหรับการขอพิมพ์ มันบอกว่า sys. คือ ST เมื่อมีการรับประกันว่าไม่มีข้อผิดพลาดประเภทเวลาทำงาน ตัวอย่าง: ML, Haskell สิ่งนี้มีประโยชน์ในการทำให้ระบบละเว้นแท็กประเภทภายในออบเจ็กต์และอย่างไรก็ตามใช้ตัวดำเนินการกับประเภทที่ถูกต้อง เนื่องจากเราทราบก่อนการดำเนินการว่าไม่จำเป็นต้องมีแท็กในออบเจ็กต์ เนื่องจาก C มีการแคสต์และตัวชี้ในการเข้าถึงบันทึกโดยพลการ C จึงไม่ใช่ st
alinsoar

0

ฉันจะบอกว่า C ถูกพิมพ์อย่างรุนแรงตามที่คอมไพเลอร์ / แพลตฟอร์มของคุณกำหนด ตัวอย่างเช่นหากคุณกำลังสร้างบนแพลตฟอร์มที่เข้มงวดการยกเลิกการอ้างอิงประเภทตัวชี้ที่ถูกเจาะมีแนวโน้มที่จะทำลาย:

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

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



-1

ไม่ได้พิมพ์อย่างรุนแรง

พิจารณาสิ่งที่ต้นแบบฟังก์ชันต่อไปนี้บอกคุณเกี่ยวกับชนิดข้อมูลของอาร์กิวเมนต์:

ไม่มีอะไร ดังนั้นฉันขอแนะนำว่าการพิมพ์ที่แข็งแกร่งไม่ได้ใช้ที่นี่


ฮะ? มันบอกว่าคุณมี int ตามด้วย char ตามด้วยอาร์กิวเมนต์ประเภทใดก็ได้ นั่นไม่ใช่ "ไม่มีอะไร"
Lawrence Dol

... ไม่บอกคุณเกี่ยวกับประเภทของอาร์กิวเมนต์ที่ส่งผ่าน เป็นเรื่องจริงที่ประเภทของฟังก์ชันนั้นรู้เอง นั่นคือสิ่งที่ Software Monkey กล่าว
Johannes Schaub - litb

"อาร์กิวเมนต์ประเภทใดก็ได้" เหล่านี้คือสิ่งที่ฉันกำลังพูดถึง โซ่มีความแข็งแรงพอ ๆ กับลิงค์ที่อ่อนแอที่สุดเท่านั้น
joel.neely

-3

ฉันจะบอกว่ามันเป็นประเภทที่ชัดเจนเนื่องจากทุกนิพจน์มีประเภทที่ไม่ใช่ฟังก์ชันของค่าของมัน ei สามารถทราบได้ก่อนรันไทม์

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


3
ไม่เป็นอะไร คำจำกัดความของฉันที่พิมพ์ผิดหรือ C?
BCS
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.