เหตุใด C ++ จึงเป็นที่โดดเด่นในการเขียนโปรแกรมการแข่งขันและการแข่งขัน? [ปิด]


23

ฉันเข้าใจว่า C ++ เป็นภาษาที่รวดเร็วมาก แต่ไม่ใช่ C เร็วหรือเร็วกว่าในบางกรณี?

จากนั้นคุณอาจบอกว่า C ++ มี OOP แต่จำนวน OOP ที่คุณต้องการสำหรับปริศนาการเขียนโปรแกรมส่วนใหญ่นั้นไม่ใหญ่มากและในความคิดของฉัน C จะสามารถจัดการได้

นี่คือเหตุผลที่ฉันถามสิ่งนี้ : ฉันสนใจการเขียนโปรแกรมการแข่งขันและการแข่งขันและฉันคุ้นเคยกับการเขียนโปรแกรมใน C อย่างไรก็ตามฉันสังเกตเห็นว่าคนส่วนใหญ่ใช้ C ++ (เช่น 17 จาก 25 ผู้เข้ารอบสุดท้ายใน Google Code Jam 2011 ใช้มันในขณะที่ไม่มีใครใช้ C) ดังนั้นฉันสงสัยว่าฉันจะเสียเปรียบกับ C.

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

สำหรับพื้นหลังฉันคิดว่าตัวเองค่อนข้างเชี่ยวชาญใน C แต่ฉันเพิ่งเริ่มเรียนรู้ C ++

คำตอบ:


56

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

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

  • C ++ ช้ากว่า C. ผิด! โปรแกรม C หลายโปรแกรมเป็นโปรแกรม C ++ ที่ถูกต้องเช่นกันและโปรแกรม C เช่นนั้นควรรันด้วยความเร็วเท่ากันเมื่อคอมไพล์ด้วยคอมไพเลอร์ C หรือคอมไพเลอร์ C ++

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

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

ดังนั้นหากคุณเชื่อฉันเราได้กำหนดว่า "C ++ ไม่ได้เลวร้ายยิ่งกว่า C" อย่างมีนัยสำคัญ มาดูสิ่งที่ทำให้ C ++ ดีกว่า C:

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

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

    struct element_t {
      struct element_t *next, *prev;
      void *element;
     };
    

C ++ อนุญาตให้หนึ่งเขียนสิ่งที่ชอบ:

template <typename T>
struct element_t {
   element_t<T> *next, *prev;
   T element;
};

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

รูทีน C หมายถึง:

void qsort(void *base, size_t nmemb, size_t size,
           int(*compar)(const void *, const void *));

ในขณะที่รูทีน C ++ ถูกกำหนดเป็น

template void sort(RandomAccessIterator first, RandomAccessIterator last);

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

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

แน่นอนว่า STL ไม่ใช่ bullet เงิน - แต่มันให้ความช่วยเหลือที่ดีบ่อยครั้งมากเมื่อแก้ปัญหาทั่วไป คุณใช้รายการใน C บ่อยแค่ไหน RB-tree จะเป็นทางออกที่ดีกว่าได้บ่อยแค่ไหนถ้าคุณมีเวลาทำ? ด้วย STL คุณไม่จำเป็นต้องประนีประนอม - ใช้ต้นไม้ถ้ามันเหมาะสมกว่ามันง่ายเหมือนการใช้รายการ

ตกลงดังนั้นฉันแค่พูดถึงส่วนที่ดีเท่านั้น มีข้อเสียอะไรบ้าง? แน่นอนว่ามี อย่างไรก็ตามจำนวนของพวกเขาลดลงทุกวัน ให้ฉันอธิบาย:

  • ไม่มีคอมไพเลอร์ C ++ ที่ดีมันเป็นแบบนี้มานาน แต่คุณต้องจำไว้ว่าภาษานั้นได้มาตรฐานในปี 1998 - มันเป็นภาษาที่ซับซ้อนซับซ้อนกว่า C. มันใช้เวลานานสำหรับคอมไพเลอร์เพื่อให้ทันกับมาตรฐาน แต่จากการเขียนนี้มีคอมไพเลอร์ที่ดีสำหรับแพลตฟอร์มที่ใช้กันอย่างแพร่หลาย GCC ในเวอร์ชั่น 3.X นั้นดีมากและมันทำงานบน GNU / Linux และแพลตฟอร์ม UNIX ส่วนใหญ่ Intel มีคอมไพเลอร์ที่ดีสำหรับ Win32 - มันค่อนข้างดี แต่น่าเสียดายที่มันยังใช้ MS STL ซึ่งเป็น sub-par

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

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


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

@DocBrown: ขึ้นอยู่กับวิธีที่คุณใช้ C ++ หากคุณกำลังทำงานกับโค้ดเก่าจำนวนมากคุณต้องเข้าใจวิธีการทำงานและอาจต้องมีความรู้ C ++ เป็นอย่างมาก หากคุณเพิ่งเขียนโค้ดใหม่ (เช่นในการแข่งขัน) คุณสามารถ จำกัด ตัวเองกับสิ่งที่คุณกำลังจะใช้หลีกเลี่ยง cruft จำนวนมาก (เช่นพูดauto_ptr<>)
David Thornley

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

3

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


2

เมื่อพูดถึงการเข้ารอบสุดท้ายของ Code Jam ก่อนหน้านี้ส่วนใหญ่เกี่ยวกับห้องสมุดมากกว่าฟีเจอร์ภาษา โซลูชันการแข่งขันแทบจะไม่ใช้หลักการออกแบบ OOP ใด ๆ แต่คุณมีโอกาสที่จะดูทัวร์ส่วนใหญ่ของคอนเทนเนอร์ไลบรารีและอัลกอริทึม - สตริง, เวกเตอร์, รายการ, สแต็ก, คิว, deque, priority_queue, ชุด, แผนที่, ซับซ้อน, คู่ bitset, lower_bound, reverse, sort, find, count, nth_element, min, max, min_element, max_element, ที่ไม่ซ้ำกัน, next_permutation, ... ผู้แข่งขันที่มีทักษะจะคุ้นเคยกับพวกเขาทั้งหมดและไม่ต้องลงมือทำและ แก้ไขข้อบกพร่องใน C

Code Jam อนุญาตให้ผู้เข้าแข่งขันนำรหัสของตนเองและใช้ไลบรารี่ของบุคคลที่สามดังนั้นในทางทฤษฎีผู้เข้าแข่งขันสามารถนำสิ่งนี้ไปปฏิบัติล่วงหน้าได้ในซีอย่างไรก็ตามการแข่งขันทั้งหมดไม่อนุญาตให้ทำได้และเทมเพลตและโอเปอเรเตอร์ กว่าใน C

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