เหตุใดฉันจึงไม่ #include <bits / stdc ++. h>


267

ฉันโพสต์คำถามด้วยรหัสของฉันซึ่ง#includeคำสั่งเพียงอย่างเดียวคือ:

#include <bits/stdc++.h>

ครูของฉันบอกให้ฉันทำสิ่งนี้ แต่ในส่วนความเห็นฉันได้รับแจ้งว่าฉันไม่ควรทำ

ทำไม?


72
ฮะ. ฉันควรจะรู้ว่าจะมีรุ่นของที่using namespace std;นั่นรวมอยู่ที่ไหนสักแห่ง
user4581301

1
ทำไมส่วนหัวนี้ถึงมีอยู่ด้วย? แน่นอนไม่มีมาตรฐานรวมถึงการรวมสิ่งนี้เพราะมันจะนำขยะมากมาย? และถ้ามันไม่รวมอยู่ในที่สาธารณะรวมถึง ... แล้วทำไมมันถึงจัดส่งในการกระจาย?
Chris Beck

10
@ChrisBeck: เป็นรายละเอียดการใช้งาน มันไม่ได้เป็นส่วนหนึ่งของ "API สาธารณะ" หรือเพื่อการใช้งาน แต่มันก็ยังต้องมีการจัดส่งมิฉะนั้นจะไม่มีอะไรทำงาน มาตรฐานรวมถึงอาจไม่ใช้มันเป็นรายบุคคล แต่มันมีไว้สำหรับใช้ในส่วนหัว precompiled ดูความคิดเห็นที่ด้านบนซึ่งระบุว่า: "นี่เป็นไฟล์การใช้งานสำหรับส่วนหัวที่คอมไพล์แล้ว" .
การแข่งขัน Lightness ใน Orbit

1
@LightnessRacesinOrbit หากคุณไม่ควรใช้มันด้วยตัวคุณเองการมีอยู่ของ PCH จะช่วยได้อย่างไร? หรือ gcc ฉลาดพอที่จะเปลี่ยนไปใช้โดยอัตโนมัติเพื่อวัตถุประสงค์ PCH ในบางสถานการณ์?
Daniel H

2
@LightnessRacesinOrbit "ไม่ใช่ส่วนหนึ่งของ" public API "หรือเพื่อการใช้งาน ผิดอย่างสิ้นเชิงมันมีไว้สำหรับใช้สาธารณะเป็นส่วนหัวที่คอมไพล์แล้ว Libstdc ++ (pre) รวบรวมและติดตั้งรุ่นที่คอมไพล์แล้วของส่วนหัวนั้นดังนั้นหากคุณรวมไว้ G ++ จะรวมจริงbits/stdc++.h.gchแทนเวอร์ชันที่คอมไพล์แล้ว มันมีอยู่เพราะมันจะต้องมีอยู่เพื่อให้สามารถสร้างเวอร์ชันที่คอมไพล์แล้วได้
Jonathan Wakely

คำตอบ:


310

การรวม<bits/stdc++.h>ดูเหมือนจะเป็นสิ่งที่พบเห็นได้ทั่วไปใน Stack Overflow ซึ่งอาจเป็นสิ่งที่เพิ่งเพิ่มเข้ามาในหลักสูตรระดับชาติในปีการศึกษาปัจจุบัน

ฉันจินตนาการถึงข้อดีที่ได้รับอย่างคลุมเครือดังนี้:

  • คุณต้องเขียนเพียงหนึ่ง#includeบรรทัด
  • คุณไม่จำเป็นต้องค้นหาทุกสิ่งที่ส่วนหัวมาตรฐานอยู่

แต่น่าเสียดายที่นี้เป็นสับขี้เกียจตั้งชื่อ GCC หัวภายในโดยตรงแทนหัวมาตรฐานของแต่ละบุคคลเช่น<string>, และ<iostream> <vector>มันทำลายความสะดวกในการพกพาและส่งเสริมนิสัยแย่ ๆ

ข้อเสียรวมถึง:

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

อย่าทำมัน!


ข้อมูลมากกว่านี้:

ตัวอย่างสาเหตุที่ Quora ไม่ดี:


77
"บางทีสิ่งที่เพิ่งเพิ่มเข้ามาในหลักสูตรระดับชาติในปีการศึกษาปัจจุบัน" คนตาบอดนำคนตาบอด :(
Reinstate Monica

14

31
เพิ่งมาที่นี่ผ่านรูหนอนในคำถามอื่นดีมาก using namesapce std;สิ่งที่ทำให้นิสัยการเรียนการสอนนี้เลวร้ายก็คือว่ามันมักจะตามด้วยโดยตรง มีเพียงสองบรรทัดและตัวระบุที่ดีทุกตัวจะถูกใช้ น่าผิดหวังอย่างไม่น่าเชื่อที่จะเห็นว่ามันถูกสอน
StoryTeller - Unslander Monica

6
เกี่ยวกับตัวอย่างของโควต้าอาจมีการเลื่อนเวลา ฉันได้เยี่ยมชมหน้าวันนี้และทั้งข้อดีและข้อเสียของ <bits / stdc ++. h> ซึ่งระบุไว้ในบริบทเฉพาะของการแข่งขันการเขียนโปรแกรมออนไลน์ ฉันพบข้อสรุปของพวกเขา ok-ish
YSC

3
@EvgeniSergeev: 2KiB เป็นจำนวนมากของรหัสข้อมูลข่าวสารสัญลักษณ์ ฯลฯ เมื่อพยายามที่จะตรวจสอบผลของมัน คุณเข้าใจทุกสิ่งที่กำลังเพิ่มเข้ามาหรือไม่? สำหรับคอมไพเลอร์ของคุณ? รุ่นปัจจุบัน? เผยแพร่ทั้งหมดในระหว่าง? การเปิดตัวในอนาคตทั้งหมดหรือไม่ หากคุณต้องการตัดสินใจเลือกระหว่างความสะดวกและความถูกต้องมีเพียงตัวเลือกที่ใช้ได้
IIsspectable

47

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

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


ให้กับทุกคนที่เขียน "บทช่วยสอน" ดังกล่าว

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

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

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


35

มีเว็บไซต์ Stack แลกเปลี่ยนเรียกว่าเป็นโปรแกรมปริศนาและรหัสกอล์ฟ ปริศนาการเขียนโปรแกรมบนเว็บไซต์ที่เหมาะสมกับความหมายของการนี้ปริศนา :

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

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

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

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

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

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

สิ่งเหล่านี้ล้วนเป็นข้อคัดค้านที่ถูกต้องและถูกต้อง ดังนั้นทำไมทุกคนจะใช้ความประหลาดใจนี้?

แต่กลับกลายเป็นว่าบางคนชอบปริศนาการเขียนโปรแกรมโดยไม่ต้องกอล์ฟรหัส พวกเขารวมตัวกันและแข่งขันในกิจกรรมต่างๆเช่น ACM-ICPC, Google Code Jam และ Facebook Hacker Cup หรือบนเว็บไซต์เช่น Topcoder และ Codeforces อันดับของพวกเขาขึ้นอยู่กับความถูกต้องของโปรแกรมความเร็วในการดำเนินการและความเร็วในการส่งคำตอบ เพื่อเพิ่มความเร็วในการดำเนินการสูงสุดผู้เข้าร่วมหลายคนใช้ C ++ stdc++.hเพื่อเพิ่มความเร็วในการเข้ารหัสบางส่วนของพวกเขาใช้

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

ดังนั้นเราจึงเหลือนิสัยไม่ดี นี่คือการคัดค้านที่ถูกต้อง โดยการใช้ไฟล์ส่วนหัวนี้ผู้เข้าแข่งขันจะหลีกเลี่ยงโอกาสที่จะเรียนรู้ไฟล์ส่วนหัวมาตรฐานที่กำหนดฟังก์ชั่นที่พวกเขาใช้ในโปรแกรมของพวกเขา เมื่อพวกเขากำลังเขียนรหัสโลกแห่งความจริง (และไม่ได้ใช้stdc++.h) พวกเขาจะต้องใช้เวลาในการค้นหาข้อมูลนี้ซึ่งหมายความว่าพวกเขาจะมีประสิทธิผลน้อยลง stdc++.hนั่นคือข้อเสียของการฝึกด้วย

นี่ทำให้เกิดคำถามว่าทำไมจึงมีค่าในการมีส่วนร่วมในการเขียนโปรแกรมแข่งขันถ้ามันส่งเสริมนิสัยที่ไม่ดีเช่นการใช้stdc++.hและการละเมิดมาตรฐานการเข้ารหัสอื่น ๆ คำตอบหนึ่งก็คือผู้คนทำด้วยเหตุผลเดียวกันกับที่พวกเขาโพสต์โปรแกรมบน PP&CG: โปรแกรมเมอร์บางคนพบว่ามันสนุกที่จะใช้ทักษะการเขียนโปรแกรมในบริบทที่เหมือนเกม

ดังนั้นคำถามที่ว่าจะใช้stdc++.hลงมาได้หรือไม่นั้นจะเป็นประโยชน์ต่อความเร็วในการเขียนโปรแกรมในการแข่งขันการเขียนโปรแกรมมากกว่านิสัยที่ไม่ดีที่อาจเกิดขึ้นจากการใช้งานหรือไม่

คำถามนี้ถามว่า: "ทำไมฉันไม่ #include <bits/stdc++.h>" ฉันรู้ว่ามันถูกถามและตอบเพื่อให้จุดและคำตอบที่ยอมรับมีวัตถุประสงค์เพื่อเป็นคำตอบที่แท้จริงหนึ่งสำหรับคำถามนี้ แต่คำถามไม่ใช่ "ทำไมฉันไม่ #include <bits/stdc++.h>ในรหัสการผลิต" ดังนั้นฉันคิดว่ามันสมเหตุสมผลที่จะพิจารณาสถานการณ์อื่น ๆ ที่คำตอบอาจแตกต่างกัน


5
ฉัน upvoted แล้ว แต่มันอาจจะคุ้มค่าชี้ให้เห็นว่า "เพื่อความสนุก" เป็นเหตุผลที่ดีที่จะมีส่วนร่วมในการเขียนโปรแกรมการแข่งขัน ในทางตรงกันข้าม "การสร้างความประทับใจแก่นายจ้างที่มีศักยภาพ" ไม่ใช่ - มันจะเป็นอันตรายต่อกรณีของคุณกับฉัน
Martin Bonner สนับสนุน Monica

2
@MartinBonner ฉันรู้ว่าผู้จัดการบางคนว่าจ้างประสบการณ์การเขียนโปรแกรมการแข่งขันเป็นธงสีแดง แต่ตราบใดที่ บริษัท ซอฟต์แวร์ชั้นนำใช้ปัญหาสไตล์ CP ในการสัมภาษณ์และดำเนินการแข่งขันเขียนโปรแกรมเพื่อค้นหาผู้สมัครใหม่ CP จะยังคงได้รับความนิยมในหมู่นักพัฒนาที่ต้องการ
RedGreenCode

@RedGreenCode ฉันไม่ได้เป็นผู้จัดการ (ขอบคุณ $ DEITY) แต่บางครั้งฉันก็มีอิทธิพลต่อการจ้างงาน desitions และแน่นอนฉันเห็นการอ้างอิงถึง "โปรแกรมการแข่งขัน" เป็นธงสีแดงขนาดใหญ่ - ไม่ได้เปรียบ
Jesper Juhl

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

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

8

จาก N4606, Working Draft, มาตรฐานสำหรับการเขียนโปรแกรมภาษา C ++:

17.6.1.2 ส่วนหัว [ส่วนหัว]

  1. แต่ละองค์ประกอบของไลบรารีมาตรฐาน C ++ ถูกประกาศหรือกำหนด (ตามความเหมาะสม) ในส่วนหัว

  2. ไลบรารีมาตรฐาน C ++ จัดเตรียมส่วนหัวไลบรารี 61 C ++ ดังแสดงในตารางที่ 14

ตารางที่ 14 - ส่วนหัวของไลบรารี C ++

<algorithm> <future> <numeric> <strstream>
<any> <initializer_list> <optional> <system_error>
<array> <iomanip> <ostream> <thread>
<atomic> <ios> <queue> <tuple>
<bitset> <iosfwd> <random> <type_traits>
<chrono> <iostream> <ratio> <typeindex>
<codecvt> <istream> <regex> <typeinfo>
<complex> <iterator> <scoped_allocator> <unordered_map>
<condition_variable> <limits> <set> <unordered_set>
<deque> <list> <shared_mutex> <utility>
<exception> <locale> <sstream> <valarray>
<execution> <map> <stack> <variant>
<filesystem> <memory> <stdexcept> <vector>
<forward_list> <memory_resorce> <streambuf>
<fstream> <mutex> <string>
<functional> <new> <string_view>

ไม่มี <bits / stdc ++. h> ที่นั่น สิ่งนี้ไม่น่าแปลกใจเนื่องจากส่วนหัว <bits / ... > เป็นรายละเอียดการใช้งานและมักจะมีคำเตือน:

*  This is an internal header file, included by other library headers.
*  Do not attempt to use it directly. 

<bits / stdc ++. h> ยังมีคำเตือน:

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