ทำไมผู้คนถึงใช้ C ถ้ามันอันตรายมาก?


132

ฉันกำลังพิจารณาการเรียนรู้ C.

แต่ทำไมคนใช้ C (หรือ C ++) ถ้ามันสามารถใช้ 'อันตราย'?

โดยอันตรายฉันหมายถึงตัวชี้และสิ่งอื่นที่คล้ายคลึงกัน

เช่นเดียวกับคำถาม Stack Overflow ทำไมฟังก์ชั่นที่ได้รับมีอันตรายมากจนไม่ควรใช้? . ทำไมโปรแกรมเมอร์ไม่เพียง แต่ใช้ Java หรือ Python หรือภาษาอื่นที่รวบรวมเช่น Visual Basic?


152
เหตุใดเชฟจึงใช้มีดหากใช้งานได้ 'อันตราย'
oerkelens

78
ด้วยพลังที่ยิ่งใหญ่มาพร้อมความรับผิดชอบที่ยอดเยี่ยม
Pieter B

10
Joe Blow, สังฆราชมาก?
Matthew James Briggs

4
เพราะ "ย้อนกลับไปในวันนี้" เมื่อ C เป็นภาษาที่เราเลือกเราคาดว่าจะสามารถจัดการกับสิ่งเช่นนั้นเพราะเราต้อง ภาษาที่มีการตีความหรือไบต์ที่ช้าเกินไปเพราะโปรเซสเซอร์ของวันนั้นช้ากว่ามาก (วันนี้ฉันสามารถซื้อพีซีต่ำสุดกับ2 + GHz CPU แบบ multi-coreและ 4 GBหน่วยความจำจาก Dell ราคา $ 279. คุณมีความคิดว่าอย่างเหลือเชื่อนี้จะปรากฏขึ้นเพื่อผู้ชายอย่างผมสำหรับผู้ที่ 4 MHzเครื่องคอมพิวเตอร์หน่วยความจำ640 กิโลไบท์มีความสุข ... ) เผชิญหน้ากับมัน - กฎของมัวร์ชนะ เกม. เกิน!
บ๊อบจาร์วิส

6
@ Bob Jarvis: เกมไม่จบ หากคุณคิดว่า 2 + GHz, 4GB PC - หรือสำหรับเรื่องนั้นคลัสเตอร์ของคุณที่มีหลายร้อย 4 GHz PCs ที่มี CUDA GPUs ล่าสุดหรืออะไรก็ตาม - เร็วพอคุณไม่ได้ทำงานหนักพอ :-)
jamesqf

คำตอบ:


246
  1. C ถือกำเนิดในภาษาอื่น ๆ ที่คุณกำลังนึกถึง หลายสิ่งที่เรารู้ในขณะนี้เกี่ยวกับวิธีทำให้การเขียนโปรแกรม "ปลอดภัย" มาจากประสบการณ์กับภาษาเช่น C

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

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

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

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

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

  4. แม้ใน C เรายังได้เรียนรู้กฎและแนวทางมากมายที่มีแนวโน้มที่จะลดจำนวนข้อบกพร่องที่ร้ายกาจลงอย่างมากที่ปรากฏในทางปฏิบัติ โดยทั่วไปแล้วเป็นไปไม่ได้ที่จะใช้มาตรฐานในการบังคับใช้กฎเหล่านี้ย้อนหลังเพราะจะทำให้รหัสที่มีอยู่มากเกินไป แต่เป็นเรื่องปกติที่จะใช้คำเตือนของคอมไพเลอร์, linters และเครื่องมือวิเคราะห์แบบคงที่อื่น ๆ ส่วนย่อยของโปรแกรม C ที่ส่งผ่านเครื่องมือเหล่านี้ที่มีสีฟลายอิ้งนั้นมีความปลอดภัยมากกว่า "แค่ C" และโปรแกรมเมอร์ C ที่มีความสามารถทุกวันนี้จะใช้งานบางส่วนของมัน


นอกจากนี้คุณจะไม่ทำให้การประกวด Java obfuscated เป็นความบันเทิงในขณะที่การประกวด C ยุ่งเหยิง


7
"ตัวหารร่วมที่ต่ำที่สุด" ฟังดูน่ารังเกียจ ฉันพูดได้ว่าไม่เหมือนกับภาษาที่หนักกว่าหลายภาษา C ไม่ได้บังคับสัมภาระเพิ่ม 1 ตันที่คุณไม่ต้องการและมอบฐานที่รวดเร็วในการใช้สิ่งที่คุณต้องการ นั่นคือสิ่งที่คุณหมายถึงอะไร
underscore_d

9
"คุณไม่มีภาษาใดภาษาหนึ่งเลยถ้าไม่มีภาษาอื่น": จริง ๆ แล้วภาษาใหม่หลายภาษา (Rust, Nim, D, ... ) พยายาม สิ่งนี้จะช่วยให้การจับคู่ชุดย่อยของ "ปลอดภัย" ของภาษากับคำสั่งดั้งเดิมที่ "ไม่ปลอดภัย" คู่กันอยู่เมื่อการควบคุมระดับนี้มีความจำเป็นอย่างยิ่ง อย่างไรก็ตามทั้งหมดเหล่านี้สร้างจากความรู้ที่สะสมจาก C และ C ++ ดังนั้นจึงอาจกล่าวได้ว่าในเวลา C และ C ++ ได้รับการพัฒนาคุณไม่สามารถมีสิ่งใดสิ่งหนึ่งได้โดยปราศจากสิ่งอื่นและในปัจจุบันมีภาษาที่พยายามแบ่งพาร์ติชันออก บิต "ไม่ปลอดภัย" ของพวกเขา แต่ยังไม่ทัน
Matthieu M.

6
1) ไม่ใช่จุดที่ถูกต้อง! C ใช้คุณสมบัติจาก Algol 68 ซึ่งเป็นภาษา "ปลอดภัย" ในแง่นี้ ดังนั้นผู้เขียนจึงรู้เกี่ยวกับภาษาดังกล่าว ประเด็นอื่น ๆ นั้นยอดเยี่ยมมาก
reinierpost

4
@MatthieuM คุณอาจต้องการดูการวิจัยของ Microsoft เช่นกัน พวกเขาได้สร้างระบบปฏิบัติการที่มีการจัดการ 2-3 ครั้งในช่วงทศวรรษหรือสองปีที่ผ่านมารวมถึงบางส่วนที่ทำงานได้เร็วขึ้น (โดยไม่ได้ตั้งใจ - เป้าหมายหลักของระบบปฏิบัติการวิจัยส่วนใหญ่คือความปลอดภัยไม่ใช่ความเร็ว) กว่าระบบปฏิบัติการที่ไม่มีการจัดการเทียบเท่า . การเร่งความเร็วส่วนใหญ่เกิดจากข้อ จำกัด ด้านความปลอดภัย - การตรวจสอบการดำเนินการคงที่และแบบไดนามิกช่วยให้การเพิ่มประสิทธิภาพที่ไม่สามารถใช้ได้ในรหัสที่ไม่มีการจัดการ มีไม่น้อยที่จะดูทั้งหมดในทุกแหล่งที่มารวมอยู่ด้วย)
Luaan

3
@Luaan: Midori ดูยอดเยี่ยมมาก ฉันมักจะมองไปข้างหน้าเพื่อบทความบล็อกของ Joe
Matthieu M.

41

อันดับแรก C คือภาษาโปรแกรมระบบ ตัวอย่างเช่นถ้าคุณเขียน Java virtual machine หรือ Python interpreter คุณจะต้องใช้ภาษาการเขียนโปรแกรมระบบเพื่อเขียนมัน

ประการที่สอง C ให้ประสิทธิภาพที่ภาษาเช่น Java และ Python ทำไม่ได้ โดยทั่วไปแล้วการคำนวณประสิทธิภาพสูงใน Java และ Python จะใช้ไลบรารี่ที่เขียนด้วยภาษาที่มีประสิทธิภาพสูงเช่น C เพื่อยกระดับอย่างหนัก

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


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

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

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


19
"ถ้าคุณเขียนเครื่องเสมือน Java หรือล่าม Python คุณจะต้องใช้ภาษาการเขียนโปรแกรมระบบเพื่อเขียน" เอ่อ? คุณอธิบาย PyPy ได้อย่างไร ทำไมคุณต้องการภาษาเช่น C เพื่อเขียนคอมไพเลอร์หรือล่ามหรือเครื่องเสมือน?
Vincent Savard

10
ฉันเชื่อว่าคุณอ้างว่าคุณต้องการภาษาการเขียนโปรแกรมระบบเพื่อเขียน Java virtual machine หรือ Python interpreter เมื่อคุณพูดว่า "ถ้าคุณเขียน Java virtual machine หรือ Python interpreter คุณจะต้องใช้ภาษาการเขียนโปรแกรมระบบเพื่อเขียนมัน" หาก PyPy ไม่พอใจคุณคุณสามารถดูล่ามหรือผู้แปลที่เขียนใน Haskell หรือเพิ่มการอ้างอิงเพื่อสนับสนุนการอ้างสิทธิ์ของคุณ
Vincent Savard

16
แม้ว่าเต่านั้นจะลงไปถึงจุดหนึ่งบางอย่างเช่น PyPy ไม่สามารถอยู่ได้หากไม่มีล่ามภาษาไพ ธ อนในภาษาอื่น
Blrfl

18
@ Birfl แต่นั่นไม่ค่อยพูดอะไรมาก C ไม่สามารถเขียนได้หากไม่มีคอมไพเลอร์ชุดประกอบและคุณไม่สามารถเขียนชุดประกอบได้หากไม่มีฮาร์ดแวร์ที่ใช้งาน
gardenhead

11
ถ้า PyPy ไม่ใช่ "ภาษาการเขียนโปรแกรมระบบ" เนื่องจากคอมไพเลอร์ C เกี่ยวข้องกับบางที่ C ก็ไม่ใช่ภาษาการเขียนโปรแกรมระบบเช่นกันเนื่องจากแอสเซมเบลอร์ใช้บางแห่ง ที่จริงแล้วมันเป็นที่นิยมในการแปลภาษา C เป็นภาษาอื่นบ้างไหม? เช่น LLVM

30

ขออภัยที่จะเพิ่มอีกคำตอบ แต่ฉันไม่คิดว่าคำตอบที่มีอยู่ใด ๆ ที่อยู่ประโยคแรกของคุณโดยตรงระบุ:

'ฉันกำลังพิจารณาการเรียนรู้ C'

ทำไม? คุณต้องการที่จะทำสิ่งต่าง ๆ ที่ C มักจะใช้ในปัจจุบัน (เช่นไดรเวอร์อุปกรณ์, VM, เอ็นจิ้นเกม, ไลบรารีสื่อ, ระบบฝังตัว, เมล็ด OS)

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

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

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


2
เป็นงานที่ยอดเยี่ยมที่จะตอบคำถามที่ดูเหมือนจะเป็นคำถามจริง! วิธีที่ยอดเยี่ยมในการชื่นชมภาษา C / C ++ และ "ปลอดภัย" สำหรับทุกสิ่งที่พวกเขามีคือการลองเขียนอะไรบางอย่างเช่นโปรแกรมฐานข้อมูลอย่างง่าย คุณจะรู้สึกดีกับแต่ละวิธีที่คุณลองและดูว่าอะไรที่ทำให้คุณ คุณจะเห็นความรู้สึกเป็นธรรมชาติทั้งคู่และคุณจะพบว่าวิธีการทางธรรมชาติล้มเหลว (เช่นมันง่ายมากในการ "เรียงลำดับ" ข้อมูลดิบใน C - เพียงแค่เขียนข้อมูล!; แต่ผลลัพธ์ไม่ได้พกพาได้ดังนั้น อาจมีการใช้งาน จำกัด ) การเข้าใจความปลอดภัยนั้นเป็นเรื่องยุ่งยากเพราะปัญหาส่วนใหญ่อาจจะยากที่จะพบ
Luaan

1
@Luaan การเรียนรู้วิธีการคัดลอกสตริงโดยใช้ตัวชี้ช่วยให้คุณมีความคิดการเรียนรู้วิธีการทำอย่างปลอดภัยนั้นเป็นอีกระดับหนึ่งและขึ้นอยู่กับเป้าหมายของคน ๆ นั้นอาจไม่จำเป็น
Jared Smith

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

10
ฉันไม่เห็นด้วยกับประโยคสุดท้าย เรียนรู้วิธีการทำให้ถูกต้องก่อนพัฒนานิสัยที่ไม่ดี
glglgl

2
@glglgl IDK ถ้าฉันอ่าน (หรือเขียน) ตัวอย่างโค้ด JavaScript บนเว็บที่ฉันทำด้วยความเข้าใจว่ามันยังไม่พร้อมใช้งาน: มันจะไม่มีการจัดการข้อยกเว้นมันอาจเป็น O (n ^ 2) ฯลฯ ไม่มี จากที่จำเป็นเพื่อให้ได้จุดผ่าน ทั้งหมดนี้เป็นสิ่งจำเป็นสำหรับรหัสการผลิต ทำไมถึงแตกต่างกัน? ฉันสามารถเขียนไร้เดียงสา C สำหรับการสั่งสอนของฉันเองในขณะที่เข้าใจด้วยสติปัญญาว่าถ้าฉันอยากจะเอามันออกไปที่นั่นฉันต้องทำงานให้มากขึ้น
Jared Smith

14

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

หากต้องการพูดถึงจุดสุดท้ายของคุณทำไม C / C ++ บน Java / Python บ่อยครั้งความเร็วจะลดลง ฉันสร้างเกมและ Java / C # เพิ่งถึงความเร็วที่ดีพอสำหรับเกมที่จะเรียกใช้ ท้ายที่สุดถ้าคุณต้องการให้เกมของคุณทำงานที่ 60 เฟรมต่อวินาทีและคุณต้องการให้เกมของคุณทำงานได้มาก (การเรนเดอร์มีราคาแพงเป็นพิเศษ) คุณต้องใช้รหัสเพื่อให้ทำงานโดยเร็วที่สุด Python / Java / C # / อื่น ๆ อีกมากมายทำงานใน "interpreters" ซึ่งเป็นซอฟต์แวร์พิเศษที่จัดการกับสิ่งที่น่าเบื่อทั้งหมดที่ C / C ++ ไม่ได้เช่นการจัดการหน่วยความจำและการรวบรวมขยะ ค่าโสหุ้ยพิเศษนั้นทำให้ช้าลงเกือบทุกเกมขนาดใหญ่ที่คุณเห็นได้ทำ (ในช่วง 10 ปีที่ผ่านมา) ใน C หรือ C ++ มีข้อยกเว้นคือเอ็นจิ้นเกม Unity ใช้ C # * และ Minecraft ใช้ Java แต่เป็นข้อยกเว้นไม่ใช่กฎ โดยทั่วไปแล้ว

* แม้แต่ Unity ไม่ใช่ C # ทั้งหมดชิ้นใหญ่ของมันคือ C ++ และคุณเพียงแค่ใช้ C # สำหรับโค้ดเกมของคุณ

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

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

เพื่อตอบสนองต่อความคิดเห็น "เพิ่งถึงความเร็ว" ใช่การเพิ่มความเร็วของ C # ส่วนใหญ่มาจากฮาร์ดแวร์ที่ดีกว่า แต่เนื่องจาก. NET Framework และ C # คอมไพเลอร์ได้รับการปรับปรุง

เกี่ยวกับ "เกมเขียนขึ้นในภาษาเดียวกับเอ็นจิ้น" ความคิดเห็นมันขึ้นอยู่กับ บางคนมี แต่ส่วนมากจะเขียนด้วยภาษาผสม ลวงตาสามารถทำ UnrealScript และ C ++, Unity ทำ C # Javascript และ Boo, เอ็นจิ้นอื่น ๆ อีกมากมายที่เขียนด้วย C หรือ C ++ ใช้ Python หรือ Lua เป็นภาษาสคริปต์ ไม่มีคำตอบง่ายๆ

และเพราะมันทำให้ฉันอ่านว่า "ใครสนใจว่าเกมของคุณทำงานที่ 200fps หรือ 120fps" ถ้าเกมของคุณทำงานเร็วกว่า 60fps คุณอาจเสียเวลากับซีพียูเนื่องจากจอภาพทั่วไปไม่ได้รีเฟรชเลย รวดเร็ว บางส่วนที่สูงกว่าและที่ใหม่กว่าทำ แต่ไม่ใช่มาตรฐาน (ยัง ... )

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


4
" C # สำหรับ Windows ทุกอย่าง " - โอ้นั่นเป็นความเข้าใจผิด และคุณยังให้ตัวอย่าง เอกภาพ AFAIK มันไม่ได้เขียนไว้ให้ C # API เพราะภาษาดีปรับตัวได้ มันออกแบบมาอย่างดีจริงๆ และฉันชอบ c ++ มากกว่า แต่ควรได้รับเครดิตเมื่อถึงกำหนด คุณอาจผสม C # กับ. NET? พวกเขาออกไปเที่ยวด้วยกันบ่อยครั้ง
luk32

2
"แม้แต่ Unity ไม่ใช่ C # ทั้งหมดชิ้นใหญ่ ๆ ของมันคือ C ++" และ? เกมใน Unity มักจะใช้ C # อย่างกว้างขวางและได้เล่นมานานพอสมควรแล้ว การแนะนำว่า C # คือ 'เพิ่งถึงความเร็ว' ต้องการบริบทมากขึ้นหรือเสี่ยงต่อการตาบอดกับเทคโนโลยีหลายสิบปีนี้
NPSF3000

2
เกือบทุกเกมขนาดใหญ่เขียนด้วยภาษาของเอ็นจิ้นที่ใช้: จำนวนงานที่ต้องทำซ้ำมีขนาดใหญ่มากจนไม่มีการพิจารณาทางเทคนิคอื่น ๆ ที่ควรคำนึงถึง การแสดงผลนั้นมีราคาแพง แต่ทุกวันนี้ทั้งหมดนี้เขียนด้วยเฉดสีและภาษาของวงตรรกะนั้นไม่เกี่ยวข้อง
Peter Taylor

2
C # ได้รับการรวบรวมโดย JIT เสมอ (ซึ่งแตกต่างจาก Java, ซึ่งความคิดเห็นของคุณถูกต้อง) และมันก็ค่อนข้างมีความสามารถในการดำเนินการที่คล้ายกันมากกับ C ++ ตั้งแต่เริ่มต้นถ้าคุณรู้ว่าคุณกำลังทำอะไรอยู่ นั่นคือปี 2003 - ไม่ใช่สิ่งที่ฉันจะพิจารณาล่าสุด ความเร็วที่ไม่ได้เป็นปัญหาหลักสำหรับเกม (โดยเฉพาะอย่างยิ่งกับโปรแกรมที่สร้างเฉดสีบน GPU) มีสิ่งอื่น ๆ ที่ทำให้ภาษาเช่น C # เป็นที่นิยมมากขึ้นหรือน้อยลงในบางครั้ง ปัญหาหลักสองประการคือ API (ซึ่งมี C-oriented หนักและการเชื่อมต่ออาจมีราคาแพง) และ GC (ส่วนใหญ่ใช้สำหรับปัญหาด้านเวลาในการตอบสนองไม่ใช่การรับส่งข้อมูลดิบ)
Luaan

1
@gbjbaanb ไม่ใช่แค่ซีพียูที่เร็วขึ้น แต่เรื่องใหญ่ก็คือ C ++ และ C มีหลายสิบปีในการคอมไพเลอร์และรันไทม์ที่สมบูรณ์แบบในขณะที่ Java เริ่มต้นจากศูนย์ (ถูกออกแบบมาเป็นแพลตฟอร์มหลายแพลตฟอร์มเป็นหลัก) เมื่อ VM ปรับปรุง (เช่นสวิตช์จากล่ามไปเป็นคอมไพเลอร์ JIT ปรับปรุง GC ... ) ดังนั้นประสิทธิภาพของแอปพลิเคชัน Java จึงทำได้ ขอบ C / C ++ ยังคงมีอยู่มากมายอยู่ในแนวทาง "หวังว่าจะไม่มีอะไรแตก" - หลีกเลี่ยงการตรวจสอบจำนวนมากที่ถือว่า "ไม่จำเป็น" แต่มันก็ยังคงเป็นหน่วยความจำขนาดใหญ่ - อันที่จริงแล้วการปรับปรุงการใช้งาน CPU มักหมายถึงประสิทธิภาพของหน่วยความจำแย่ลง :)
Luaan

13

มันตลกที่คุณอ้างว่า C ไม่ปลอดภัยเพราะ "มีพอยน์เตอร์" ตรงข้ามเป็นจริง: Java และ C # มีพอยน์เตอร์จริงเท่านั้น (สำหรับประเภทที่ไม่ใช่เจ้าของภาษา) ข้อผิดพลาดที่พบบ่อยที่สุดใน Java น่าจะเป็น Null Pointer Exception (เปรียบเทียบจากhttps://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Monyake -Hoare ) ข้อผิดพลาดที่พบบ่อยที่สุดอันดับที่สองคืออาจมีการอ้างอิงที่ซ่อนอยู่กับวัตถุที่ไม่ได้ใช้ (เช่นการปิดการสนทนาไม่ได้ถูกกำจัด) ซึ่งไม่สามารถเผยแพร่ได้ซึ่งนำไปสู่โปรแกรมที่ใช้งานมานาน

มีกลไกพื้นฐานสองอย่างที่ทำให้ C # และ Java ปลอดภัยยิ่งขึ้นและปลอดภัยขึ้นในสองวิธี:

  • การรวบรวมขยะทำให้มีโอกาสน้อยที่โปรแกรมจะพยายามเข้าถึงวัตถุที่ถูกทิ้ง ทำให้โปรแกรมมีโอกาสน้อยที่จะยกเลิกโดยไม่คาดคิด ตรงข้ามกับ C, Java และ C # โดยค่าเริ่มต้นจัดสรรข้อมูลที่ไม่ใช่เจ้าของภาษาแบบไดนามิก สิ่งนี้ทำให้ตรรกะของโปรแกรมมีความซับซ้อนมากขึ้น แต่คอลเลกชันขยะในตัวมีค่าใช้จ่ายสูง

ตัวชี้สมาร์ท C ++ 'ล่าสุดทำให้งานนั้นง่ายขึ้นสำหรับโปรแกรมเมอร์

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

เป็นที่น่าสังเกตว่าแม้ว่าเวลาการทำงานที่ซับซ้อนยังเป็นความเสี่ยงด้านความปลอดภัย สำหรับฉันแล้ว Oracle กำลังอัพเดท JVM ทุกสองสามสัปดาห์เนื่องจากปัญหาด้านความปลอดภัยที่ค้นพบใหม่ แน่นอนว่ามันยากที่จะตรวจสอบ JVM มากกว่าโปรแกรมเดียว

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

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


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

1
นอกจากนี้stackoverflow.com/questions/57483/ … - จะแม่นยำกว่าหากกล่าวว่า java มี "การอ้างอิงในทางปฏิบัติเท่านั้น"
Sam Dufel

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

การยืนยันว่า JVM ของ Oracle ดูด (จากจุดยืนของการตกเลือดที่มีช่องโหว่ด้านความปลอดภัยที่มีช่องโหว่) และดังนั้นเวลาของภาษาที่ได้รับการจัดการโดยทั่วไปแนะนำข้อกังวลด้านความปลอดภัยมากกว่าการใช้ภาษาที่มีการจัดการ การเล่นวิดีโอและภาพเคลื่อนไหวจากเว็บไซต์จะต้องไม่ปลอดภัยอย่างน่าขัน ไม่ใช่รันไทม์ Java ทั้งหมดเกือบจะไม่ดีเท่าการเกลียดชัง JVM ในปี 1990 ของ Oracle / Sun และไม่ใช่ภาษาที่ได้รับการจัดการทั้งหมดคือ Java (ดีอย่างเห็นได้ชัด.)
mostlyinformed

@Halfinformed ดี; ฉันบอกว่าโปรแกรมนั้นปลอดภัยพอ ๆ กับรันไทม์และโปรแกรม "เฉลี่ยของคุณ" (อ่าน: small-ish) สามารถใช้ความพยายามได้อย่างปลอดภัยกว่ารันไทม์ขนาดใหญ่เช่นล่ามรหัสไบท์ ข้อความนั้นดูเหมือนจะปฏิเสธไม่ได้ ไม่ว่าโปรแกรมแบบสแตนด์อโลนเฉพาะหรือรันไทม์เฉพาะใด ๆ จะมีความปลอดภัยมากกว่าหรือน้อยกว่านั้นขึ้นอยู่กับความซับซ้อนและการออกแบบการเข้ารหัสและคุณภาพการบำรุงรักษาที่เกี่ยวข้อง ตัวอย่างเช่นฉันจะไม่พูดว่า sendmail นั้นปลอดภัยกว่า Java VM ของ Oracle แต่ qmail อาจเป็น
Peter A. Schneider

10

เนื่องจากความเร็ว "ความปลอดภัย" ค่าใช้จ่ายภาษา "ปลอดภัย" จึงทำงานที่ความเร็วช้าลง

คุณถามว่าทำไมใช้ภาษา "อันตราย" เช่น C หรือ C ++ มีบางคนเขียนโปรแกรมควบคุมวิดีโอหรือเช่นใน Python หรือ Java ฯลฯ และดูว่าคุณรู้สึกอย่างไรกับ "ความปลอดภัย" :)

อย่างจริงจังแม้ว่าคุณจะต้องใกล้เคียงกับหน่วยความจำหลักของเครื่องเพื่อให้สามารถจัดการพิกเซล, รีจิสเตอร์, ฯลฯ ... Java หรือ Python ไม่สามารถทำสิ่งนี้ได้ด้วยความเร็วที่คุ้มค่ากับประสิทธิภาพ ... C และ C ++ อนุญาตให้คุณทำเช่นนี้ผ่านตัวชี้และสิ่งที่คล้ายกัน ...


20
มันไม่เป็นความจริงโดยทั่วไปว่าค่าใช้จ่ายด้านความปลอดภัยความเร็ว ภาษาที่มีความปลอดภัยที่สุดจะทำการตรวจสอบส่วนใหญ่ในเวลารวบรวม O'Caml, Ada, Haskell, Rust ไม่ได้วิ่งช้ากว่า C ในแง่ของความเร็วรันไทม์โดยเฉลี่ย สิ่งที่พวกเขาทำมักจะเกิดขึ้นเป็นค่าใช้จ่ายอย่างมีนัยสำคัญในขนาดโปรแกรมที่มีประสิทธิภาพหน่วยความจำแฝงและเห็นได้ชัดรวบรวมเวลา และใช่พวกเขามีปัญหากับสิ่งที่อยู่ใกล้กับโลหะ แต่นั่นไม่ใช่ปัญหาเรื่องความเร็ว
leftaroundabout

6
นอกจากนี้ C ไม่ได้ทำในสิ่งที่คุณคิด C เป็นเครื่องที่เป็นนามธรรม มันไม่ให้คุณเข้าถึงอะไรได้เลย - นั่นเป็นเรื่องดี คุณไม่สามารถดูชุดประกอบที่ทันสมัยเพื่อดูว่า C ซ่อนตัวจากคุณมากแค่ไหน - ชุดประกอบสมัยใหม่ (เช่น TASM) จะได้รับการพิจารณาว่าเป็นภาษาระดับสูงเมื่อ C ได้รับการพัฒนา ฉันจะมีความสุขมากถ้ามีคนเขียนไดรเวอร์ในภาษา "ปลอดภัย" ขอบคุณ - ซึ่งค่อนข้างจะช่วยหลีกเลี่ยง BSODs และการค้างเหล่านั้นมากมายไม่ต้องพูดถึงช่องโหว่ความปลอดภัย :) และที่สำคัญที่สุดคือมีภาษาระบบที่ปลอดภัยกว่ามาก กว่า C.
Luaan

3
@ Wintermute คุณต้องการค้นหา Rust ก่อนที่จะแสดงความคิดเห็นเกี่ยวกับคุณลักษณะด้านความปลอดภัยที่ต้องเสียค่าใช้จ่าย นรกระบบการพิมพ์ระดับต่ำ C ของจริงยับยั้ง optimisations มีประโยชน์มากหลายอย่างที่คอมไพเลอร์มิฉะนั้นจะทำ (โดยเฉพาะอย่างยิ่งเมื่อพิจารณาว่าสวยมากไม่มีโครงการคที่มีขนาดใหญ่พอที่จะหลีกเลี่ยงที่จะไม่ละเมิด aliasing เข้มงวดที่ไหนสักแห่ง )
Voo

7
@ Wintermute ใช่ตำนานที่คุณไม่สามารถทำให้ C / C ++ ปลอดภัยกว่านี้ได้หากไม่แนะนำค่าใช้จ่ายในการแสดงนั้นคงอยู่นานมากซึ่งเป็นเหตุผลว่าทำไมฉันถึงจริงจังมาก (มีบางพื้นที่ที่นี่เป็นเรื่องจริง ทำไมสนิมถึงไม่แพร่หลายขึ้น? ประวัติและความซับซ้อน Rust ยังค่อนข้างใหม่และมีระบบที่ใหญ่ที่สุดที่เขียนด้วย C อยู่ก่อนที่ Rust จะประดิษฐ์ขึ้นมา - คุณจะไม่เขียน LOC เป็นล้านภาษาในภาษาใหม่แม้ว่ามันจะปลอดภัยกว่าก็ตาม โปรแกรมเมอร์ทุกคนและสุนัขของพวกเขารู้ดีว่า C, Rust? ขอให้โชคดีในการหาคนพอ
Voo

3
@ Voo Dogs กำลังทำ C? ... ไม่น่าแปลกใจเลยที่ฉันเห็นโค้ดที่ไม่ดีออกมามากมาย ... j / k จุดที่เกี่ยวกับ Rust (ฉันเพิ่งดาวน์โหลดและติดตั้งมันดังนั้นคุณอาจจะมีการแปลงเพิ่มอีก) BTW เกี่ยวกับ เพื่อ Rust ทำถูกต้อง ... ฉันสามารถทำให้เดียวกันสำหรับ "D" :)
Wintermut3

9

นอกจากทั้งหมดข้างต้นแล้วยังมีอีกหนึ่งกรณีการใช้งานที่ใช้กันทั่วไปซึ่งใช้ C เป็นไลบรารี่ทั่วไปสำหรับภาษาอื่น ๆ

โดยทั่วไปเกือบทุกภาษามีส่วนต่อประสาน API กับ C

ตัวอย่างง่ายๆลองสร้างแอปพลิเคชันทั่วไปสำหรับ Linux / IOS / Android / Windows นอกเหนือจากเครื่องมือทั้งหมดที่มีอยู่สิ่งที่เราทำคือการทำ core library ใน C จากนั้นเปลี่ยน GUI สำหรับแต่ละสภาพแวดล้อมนั่นคือ:

  • IOS: ObjectiveC สามารถใช้ไลบรารี C ได้
  • Android: Java + JNI
  • Linux / Windows / MacOS: ด้วย GTK / .Net คุณสามารถใช้ห้องสมุดท้องถิ่นได้ หากคุณใช้ Python, Perl และ Ruby แต่ละรายการจะมีอินเตอร์เฟส API ดั้งเดิม (Java อีกครั้งพร้อม JNI)

สองเซ็นต์ของฉัน


หนึ่งในเหตุผลที่ฉันชอบที่จะใช้, พูด, PHP, เป็นเพราะห้องสมุดเกือบทั้งหมดเป็นของจริงเขียนใน C - ขอบคุณดังนั้นหรือ PHP จะช้าเหลือทน :) PHP เป็นที่ดีในการเขียนโค้ดเลอะเทอะโดยไม่ต้องกลัว ทำสิ่งที่ 'อันตราย' (และนั่นคือสาเหตุที่ฉันมักจะเขียนโค้ด PHP มากกว่าสิ่งอื่น - ฉันชอบรหัสเลอะเทอะ!: D) แต่ก็ดีที่ได้รู้ว่าภายใต้ฟังก์ชั่นเหล่านั้นมากมาย ห้องสมุด C เพื่อเพิ่มประสิทธิภาพ ;-) ตรงกันข้ามการเขียนโค้ดเลอะเทอะใน C นั้นไม่มีอะไรใหญ่โต ...
Gwyneth Llewelyn

7

ความยากลำบากพื้นฐานกับ C คือชื่อนี้ใช้เพื่ออธิบายจำนวนภาษาถิ่นที่มีไวยากรณ์เหมือนกัน แต่มีความหมายที่แตกต่างกันมาก บางภาษามีความปลอดภัยมากกว่าภาษาอื่น

ใน C ซึ่งออกแบบโดย Dennis Ritchie โดยทั่วไปคำสั่ง C จะถูกแมปกับคำแนะนำของเครื่องในแบบที่คาดการณ์ได้ เนื่องจาก C สามารถทำงานกับโปรเซสเซอร์ที่ทำงานแตกต่างกันเมื่อสิ่งต่าง ๆ เช่นการโอเวอร์โฟลว์ทางคณิตศาสตร์ที่ลงนามเกิดขึ้นโปรแกรมเมอร์ที่ไม่ทราบว่าเครื่องจะทำงานอย่างไรในกรณีที่โอเวอร์โฟลว์ทางคณิตศาสตร์ไม่ทราบว่าโค้ด C ที่ทำงานบนเครื่องนั้นจะทำงานอย่างไร ถ้าเป็นที่รู้กันว่าเครื่องจะทำงานในลักษณะที่แน่นอน (e กรัมสอง - ส่วนประกอบของความเงียบ) แล้ว implementations บนเครื่องนั้นจะทำเช่นเดียวกัน หนึ่งในเหตุผลที่ C มีชื่อเสียงเรื่องความรวดเร็วคือในกรณีที่โปรแกรมเมอร์รู้ว่าพฤติกรรมตามธรรมชาติของแพลตฟอร์มในสถานการณ์ขอบคดีจะเหมาะกับความต้องการของพวกเขาไม่มีความจำเป็นที่โปรแกรมเมอร์หรือคอมไพเลอร์เขียนโค้ดเพื่อสร้างสถานการณ์ดังกล่าว .

น่าเสียดายที่ผู้เขียนคอมไพเลอร์ได้รับมุมมองว่าเนื่องจากมาตรฐานไม่มีข้อกำหนดเกี่ยวกับการใช้งานที่ต้องทำในกรณีเช่นนี้ (ความหย่อนซึ่งตั้งใจจะอนุญาตให้ใช้งานฮาร์ดแวร์ที่อาจไม่ทำงานตามที่คาดการณ์) ผู้รวบรวมควรรู้สึกฟรีเพื่อสร้างรหัส ของเวลาและเวรกรรม

พิจารณาสิ่งที่ชอบ:

int hey(int x)
{
   printf("%d", x);
   return x*10000;
}
void wow(int x)
{
  if (x < 1000000)
    printf("QUACK!");
  hey(x);    
}

ทฤษฎีคอมไพเลอร์ Hyper-modern (แต่ทันสมัย) จะแนะนำว่าคอมไพเลอร์ควรส่งออก "QUACK!" โดยไม่มีเงื่อนไขเนื่องจากในกรณีใด ๆ ที่เงื่อนไขเป็นเท็จโปรแกรมจะจบลงด้วยการเรียกใช้พฤติกรรมที่ไม่ได้กำหนดซึ่งดำเนินการคูณซึ่งผลลัพธ์จะถูกละเว้นอยู่ดี เนื่องจากมาตรฐานจะอนุญาตให้คอมไพเลอร์ทำสิ่งที่ชอบในกรณีเช่นนี้จึงอนุญาตให้คอมไพเลอร์ส่งออก "QUACK!"

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


1
แม้ในคอมไพเลอร์ไฮเปอร์โมเดิร์น C ไม่ได้ตรวจสอบขอบเขตในอาร์เรย์ หากทำเช่นนั้นนั่นจะไม่เข้ากันกับคำจำกัดความของภาษา ฉันใช้ความจริงนั้นบางครั้งเพื่อจัดทำอาร์เรย์ด้วยตัวชี้เพิ่มเติมเข้าไปตรงกลางของอาร์เรย์เพื่อให้มีดัชนีติดลบ
robert bristow-johnson

1
ฉันต้องการเห็นหลักฐานตัวอย่างของคุณที่ผลิต "QUACK!" โดยไม่มีเงื่อนไข x แน่นอนอาจมากกว่า 1000000 ณ จุดเปรียบเทียบและการประเมินในภายหลังซึ่งจะส่งผลให้เกิดโอเวอร์โฟลว์ไม่ได้ป้องกันสิ่งนั้น ยิ่งไปกว่านั้นถ้าคุณเปิดใช้งานอินไลน์ซึ่งอนุญาตให้ลบคูณล้นออกได้อาร์กิวเมนต์ของคุณเกี่ยวกับข้อ จำกัด ของช่วงโดยนัยจะไม่ถูกเก็บไว้
เกรแฮม

2
@ robertbristow-johnson: ที่จริงแล้ว Standard ค่อนข้างบอกอย่างชัดเจนว่าให้เช่นint arr[5][[5]ความพยายามในการเข้าถึงarr[0][5]จะให้ผลพฤติกรรมที่ไม่ได้กำหนด กฎดังกล่าวจะทำให้มันเป็นไปได้สำหรับคอมไพเลอร์ที่จะได้รับสิ่งที่ต้องการarr[1][0]=3; arr[0][i]=6; arr[1][0]++;ที่จะอนุมานได้ว่าarr[1][0]จะเท่ากับ 4 iโดยไม่คำนึงถึงความคุ้มค่าของ
supercat

2
@ robertbristow-johnson: แม้ว่าคอมไพเลอร์จะจัดสรรอาร์เรย์ภายใน struct ตามลำดับโดยไม่มีช่องว่างนั่นไม่รับประกันว่าการทำดัชนีหนึ่งในอาร์เรย์จะรับประกันว่าจะส่งผลกระทบต่ออีก ดูgodbolt.org/g/Avt3KWสำหรับตัวอย่างของวิธี gcc จะปฏิบัติต่อรหัสดังกล่าว
supercat

1
@ robertbristow-johnson: ฉันแสดงความคิดเห็นต่อสมัชชาเพื่ออธิบายสิ่งที่กำลังทำอยู่ คอมไพเลอร์เห็นว่ารหัสเก็บ 1 ลงใน s-> arr2 [0] และเพิ่มขึ้น s-> arr2 [0] ดังนั้น gcc รวมสองการดำเนินการโดยมีรหัสเพียงเก็บค่าค่า 2 โดยไม่คำนึงถึงความเป็นไปได้ว่าการแทรกแซงการเขียน เพื่อ s-> arr1 [i] อาจส่งผลต่อค่าของ s-> arr1 [0] (เนื่องจากตามมาตรฐานไม่สามารถทำได้)
supercat

5

เหตุผลทางประวัติศาสตร์ ฉันไม่ได้มักจะเขียนรหัสใหม่ส่วนใหญ่ฉันจะรักษาและขยายสิ่งเก่าที่ได้รับการทำงานมานานหลายทศวรรษ ฉันแค่ดีใจที่มันเป็น C และไม่ใช่ Fortran

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


5

"อันตราย" คืออะไร?

การอ้างว่า C เป็น "อันตราย" เป็นจุดพูดคุยบ่อยในสงครามเปลวไฟทางภาษา (ส่วนใหญ่มักเปรียบเทียบกับ Java) อย่างไรก็ตามหลักฐานการอ้างสิทธิ์นี้ยังไม่ชัดเจน

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

นอกจากนี้"อันตราย" ขึ้นอยู่กับบริบท: คุณพยายามทำอะไรและคุณมีความเสี่ยงประเภทใด

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

อย่างไรก็ตาม C และ C ++ ใช้กันอย่างแพร่หลายสำหรับระบบที่มีความสำคัญต่อภารกิจเนื่องจากภาษาที่เล็กกว่าที่มีการควบคุม hardward โดยตรงมากขึ้นถือว่าเป็น "ปลอดภัย" ในบริบทนั้น จากคำตอบ Stack Overflow ที่ดีมาก :

แม้ว่า C และ C ++ ไม่ได้ออกแบบมาสำหรับแอพพลิเคชั่นประเภทนี้โดยเฉพาะ แต่ก็มีการใช้กันอย่างแพร่หลายสำหรับซอฟต์แวร์ฝังตัวและความปลอดภัยที่สำคัญด้วยเหตุผลหลายประการ คุณสมบัติหลักของ note คือการควบคุมการจัดการหน่วยความจำ (ซึ่งช่วยให้คุณหลีกเลี่ยงการรวบรวมขยะ), ไลบรารีรันไทม์หลักที่ดีและบั๊กที่ดีและการสนับสนุนเครื่องมือสำหรับผู้ใหญ่ โซ่เครื่องมือพัฒนาแบบฝังจำนวนมากที่ใช้อยู่ในปัจจุบันได้รับการพัฒนาเป็นครั้งแรกในปี 1980 และ 1990 เมื่อเป็นเทคโนโลยีปัจจุบันและมาจากวัฒนธรรม Unix ที่แพร่หลายในขณะนั้นดังนั้นเครื่องมือเหล่านี้จึงเป็นที่นิยมสำหรับงานประเภทนี้

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


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

5

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

นั่นเป็นสาเหตุที่ผู้คนใช้ C - เพื่อสร้างเครื่องมือที่อันตรายน้อยกว่าที่คุณต้องการใช้


2

อนุญาตให้ฉันใช้ถ้อยคำใหม่คำถามของคุณ:

ฉันกำลังพิจารณาการเรียนรู้ [เครื่องมือ]

แต่ทำไมคนใช้ [เครื่องมือ] (หรือ [เครื่องมือที่เกี่ยวข้อง]) หาก [พวกเขา] สามารถใช้ 'อันตราย'

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

ตัวอย่างเช่นหากคุณต้องการใส่เส้นผ่านศูนย์กลาง 6 มม., รูลึก 5 ซม., ทรงกระบอกในบล็อกของไม้การเจาะเป็นเครื่องมือที่ดีกว่าตัวแยกวิเคราะห์ LALR หากคุณรู้ว่าเครื่องมือสองชนิดนี้คืออะไรคุณรู้ว่าเครื่องมือใดเหมาะสม หากคุณรู้วิธีใช้สว่านแล้วรู voila !,

C เป็นเพียงเครื่องมืออื่น มันจะดีกว่าสำหรับงานบางอย่างมากกว่างานอื่น ๆ คำตอบอื่น ๆ ที่อยู่นี้ หากคุณเรียนรู้ C คุณจะได้รับการยอมรับว่าเป็นเครื่องมือที่ถูกต้องหรือไม่


คำตอบจำนวนนี้คือเหตุผลที่คำถามถูกโยนออกมาว่า "อิงตามความคิดเห็นเป็นหลัก" อย่าพูดว่า C มีข้อได้เปรียบพูดในสิ่งที่มันเป็น!
reinierpost

1

ฉันกำลังพิจารณาการเรียนรู้ค

ไม่มีเหตุผลที่เฉพาะเจาะจงที่จะไม่เรียนรู้ C แต่ฉันอยากจะแนะนำ C ++ มันเสนอสิ่งที่ C ทำมาก (เนื่องจาก C ++ เป็นชุดสุดยอดของ C) ที่มี "extras" จำนวนมาก การเรียนรู้ C ก่อน C ++ นั้นไม่จำเป็น - เป็นภาษาที่แยกกันได้อย่างมีประสิทธิภาพ

อีกวิธีหนึ่งถ้า C เป็นชุดเครื่องมืองานไม้มันอาจจะเป็น:

  • ค้อน
  • เล็บ
  • เลื่อยมือ
  • สว่านมือ
  • ซานเดอร์บล็อก
  • สิ่ว (อาจจะ)

คุณสามารถสร้างอะไรก็ได้ด้วยเครื่องมือเหล่านี้ - แต่สิ่งที่ดีอาจต้องใช้เวลาและทักษะมากมาย

C ++ คือชุดเครื่องมือไฟฟ้าที่ร้านฮาร์ดแวร์ในพื้นที่ของคุณ

หากคุณยึดติดกับคุณสมบัติทางภาษาพื้นฐานในการเริ่มต้น C ++ จะมีช่วงการเรียนรู้เพิ่มเติมเล็กน้อย

แต่ทำไมคนใช้ C (หรือ C ++) ถ้ามันสามารถใช้ 'อันตราย'?

เพราะบางคนไม่ต้องการเฟอร์นิเจอร์จาก IKEA =)

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

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

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

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

ทำไมโปรแกรมเมอร์ไม่เพียง แต่ใช้ Java หรือ Python หรือภาษาอื่นที่รวบรวมเช่น Visual Basic?

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

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

ในระยะสั้นการเพิ่มสิ่งต่าง ๆ อาจทำให้เกิดความล่าช้าหรือทำให้เกิดความซับซ้อนที่ไม่ต้องการ

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

ในความเป็นจริงการแนะนำอะไร "พิเศษ" อาจช้าหรือซับซ้อนรหัสของคุณ ในภาษา "ที่ไม่มีตัวชี้ที่น่ากลัว" คุณมักจะรอบิตของรหัสอื่น ๆ เพื่อทำความสะอาดหลังคุณหรือหาวิธี "ปลอดภัย" ที่จะทำสิ่งต่าง ๆ - เนื่องจากโปรแกรมของคุณยังคงดำเนินการเข้าถึงหน่วยความจำแบบเดียวกับที่อาจทำได้ ชี้ คุณไม่ใช่คนที่จัดการมัน (ดังนั้นคุณจึงไม่สามารถ f * ck มันได้อัจฉริยะ = P)

โดยอันตรายฉันหมายถึงตัวชี้และสิ่งอื่นที่คล้ายคลึงกัน [... ] เช่นเดียวกับคำถาม Stack Overflow เหตุใดฟังก์ชันที่ได้รับจึงอันตรายที่ไม่ควรใช้

ตามคำตอบที่ยอมรับ:

"มันยังคงเป็นส่วนหนึ่งของภาษาอย่างเป็นทางการจนถึงมาตรฐาน ISO 1999 C แต่มันก็ถูกลบออกอย่างเป็นทางการโดยมาตรฐาน 2011 การใช้งาน C ส่วนใหญ่ยังคงสนับสนุน แต่อย่างน้อย gcc ออกคำเตือนสำหรับรหัสใด ๆ ที่ใช้มัน"

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

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

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

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

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

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


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

"การเขียน C ++ ที่ดีนั้นยากกว่าการเขียน C ที่ดี" - แน่นอน =) "[R] eading C ++ ยากกว่าการอ่าน C" - การเขียนโปรแกรมขั้นสูงใด ๆ ที่แยกไม่ออกจากเวทย์มนตร์ ;-) สอง cents ของฉันคือว่านี่ขึ้นอยู่กับโปรแกรมเมอร์มากกว่าพึ่งพาภาษา แต่ C ++ ไม่ได้ช่วยอะไรมาก ในหมวดนี้ "ดังนั้นช่วงการเรียนรู้ของ C ++ จึงยิ่งชันมาก" - ในระยะยาวใช่ ในระยะสั้นน้อยลง (ความเห็นของฉัน) โดยทั่วไปแล้วหลักสูตรภาษาพื้นฐานส่วนใหญ่ใน C และ C ++ มีแนวโน้มที่จะครอบคลุมเนื้อหาประเภทเดียวกันโดยทั่วไปยกเว้นคลาสเรียนสำหรับ C ++
Anaksunaman

2
"พวกเขามีข้อดีและการใช้งานที่แตกต่างกันและแต่ละอันมีคุณสมบัติที่อีกอันหนึ่งไม่มี" - ตามที่กล่าวไว้ "ไม่มีเหตุผลที่เฉพาะเจาะจงที่จะไม่เรียนรู้ C [.]" C เป็นภาษาที่ดีและฉันติดอยู่กับที่ ถ้ามันเหมาะกับ OP หรือใครก็ตามฉันสนับสนุนการเรียนรู้อย่างเต็มที่ =)
Anaksunaman

การเรียนรู้ C สอนให้คุณรู้ว่าเครื่องจักรทำงานอย่างไร (ไม่ลงทั้งหมด แต่ก็ยังใกล้กับโลหะมากขึ้น) นั่นเป็นเหตุผลที่ดีมากสำหรับการเรียนรู้
Agent_L

1

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

บางครั้งคุณจะพบว่าปัญหายืมตัวเองดีกับสิ่งที่รวมอยู่ในไลบรารีเริ่มต้นของ Java ในกรณีเช่นนี้คุณอาจเลือก Java เพื่อใช้ประโยชน์นั้น ในกรณีอื่น ๆ อาจเป็นไปได้ว่าคุณต้องทำอะไรบางอย่างใน Windows ที่ง่ายกว่ามากในรันไทม์. NET ดังนั้นคุณอาจใช้ C # หรือ VB อาจมีเครื่องมือกราฟิกหรือสคริปต์คำสั่งที่จะแก้ปัญหาของคุณแล้วคุณสามารถใช้เหล่านี้ บางทีคุณอาจจำเป็นต้องเขียนแอปพลิเคชัน GUI บนหลายแพลตฟอร์ม Java อาจเป็นตัวเลือกเนื่องจากมีไลบรารีที่รวมอยู่ใน JDK แต่แล้วอีกครั้งหนึ่งแพลตฟอร์มเป้าหมายอาจไม่มี JRE ดังนั้นคุณอาจเลือก C และ SDL (หรือคล้ายกัน) แทน

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

บรรทัดล่างคือคุณควรเรียนรู้เครื่องมือภาษาและกระบวนทัศน์ให้ได้มากที่สุด

โปรดอยู่ห่างจากความคิด: "ฉันเป็นโปรแกรมเมอร์ X" (X = C, C ++, Java ฯลฯ )

เพียงแค่ใช้ "ฉันเป็นโปรแกรมเมอร์"

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

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


0

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


0

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

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

ในความเป็นจริงมันยากที่จะทำงานใน C ++ ซึ่งเป็นภาษาที่ปลอดภัยโดยรวมในบริบทระดับต่ำของบิตและไบต์โดยไม่ต้องเขียนโค้ดที่เป็นอันตรายมากกว่าที่คุณทำใน C เนื่องจากคุณสามารถทำบูลดอซผ่านระบบพิมพ์ของ C ++ เขียนทับ vptrs และไม่สามารถเรียกใช้ copy constructors และ destructors ในเวลาที่เหมาะสม หากคุณใช้เวลาที่เหมาะสมในการเคารพประเภทเหล่านี้และใช้ตำแหน่งใหม่และเรียกใช้ dtors ด้วยตนเองและอื่น ๆ คุณจะได้สัมผัสกับโลกแห่งการจัดการข้อยกเว้นในบริบทที่ต่ำเกินไปสำหรับ RAII ที่จะปฏิบัติได้และบรรลุข้อยกเว้น - ความปลอดภัยในบริบทระดับต่ำนั้นเป็นเรื่องยากมาก (คุณต้องแกล้งทำเป็นเหมือนฟังก์ชั่นใด ๆ ที่สามารถโยนและจับความเป็นไปได้ทั้งหมดและย้อนกลับผลข้างเคียงใด ๆ เป็นการทำธุรกรรมที่แยกไม่ออก รหัส C มักจะ "

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

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

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

มันง่ายที่จะนำสิ่งนี้ไปให้ได้ ฉันจำโพสต์ facebook กับคนที่ชี้ให้เห็นว่าเป็นไปได้ที่จะสร้างวิดีโอเกม 3 มิติด้วย Python โดยนัยว่าภาษาระดับต่ำกำลังล้าสมัยและเป็นเกมที่ดูดี แต่ Python กำลังทำการโทรระดับสูงเข้าสู่ไลบรารี่ที่ติดตั้งใน C เพื่อทำงานหนักทั้งหมด คุณไม่สามารถสร้าง Unreal Engine 4 เพียงแค่ทำการโทรระดับสูงเข้าสู่ไลบรารีที่มีอยู่ Unreal Engine 4 คือห้องสมุด. มันทำทุกสิ่งที่ไม่เคยมีอยู่ในห้องสมุดและเอ็นจิ้นอื่น ๆ ตั้งแต่แสงไปจนถึงแม้แต่ระบบพิมพ์เขียวที่สำคัญและวิธีที่มันสามารถรวบรวมและรันโค้ดได้ทันที หากคุณต้องการสร้างสรรค์สิ่งใหม่ ๆ ในระดับเอ็นจิ้น / แกน / เคอร์เนลต่ำคุณจะต้องได้ระดับต่ำ หากเกมทั้งหมดเปลี่ยนไปใช้ภาษาที่ปลอดภัยระดับสูงจะไม่มี Unreal Engine 5 หรือ 6 หรือ 7 เป็นไปได้ว่าผู้คนยังคงใช้ Unreal Engine 4 ทศวรรษต่อมาเพราะคุณไม่สามารถคิดค้นสิ่งใหม่ ๆ ได้ในระดับที่ต้องการ ออกมาพร้อมกับเอ็นจิ้นถัดไปโดยเพียงแค่ทำการโทรระดับสูงเข้าสู่ระบบเก่า

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