มีการใช้อักษรตัวพิมพ์ใหญ่ร่วมกันใน C ++ หรือไม่ [ปิด]


13

ฉันทำงานเป็นจำนวนมากใน Python และ Java และทั้งสองภาษานั้นมีหลักการทั่วไป (แม้ว่าจะไม่ใช่สากล) ว่าควรใช้ตัวพิมพ์ใหญ่ในตัวระบุอย่างไร: ใช้ทั้งPascalCaseชื่อคลาสและALL_CAPSค่าคงที่ "ทั่วโลก" แต่สำหรับตัวระบุอื่น ๆ มากรหัส Java ใช้ในขณะที่จำนวนมากของงูใหญ่ใช้รหัสmixedCase underscore_delimitersฉันรู้ว่าไม่มีภาษาหรือห้องสมุดบังคับใช้ตัวพิมพ์ใหญ่ แต่อย่างใด แต่ฉันพบว่าเมื่อฉันติดกับอนุสัญญามาตรฐานสำหรับภาษาที่ฉันใช้รหัสของฉันดูเหมือนจะอ่านได้มากขึ้น

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


ปัญหาของ camelCase คือมันไม่ได้เล่นกับ preprocessor อย่างดี ไม่ใช่ปัญหาใหญ่โดยเฉพาะเมื่อตัวประมวลผลล่วงหน้าสามารถหลีกเลี่ยงได้
Pubby

ฉันต้องเผชิญกับการตัดสินใจครั้งนี้เมื่อไม่กี่วันที่ผ่านมา ในท้ายที่สุดมันก็ไม่ใช่เรื่องง่ายเพราะทั้งไลบรารีมาตรฐานและบูสต์ใช้ underscore_lowercase_delimiters เนื่องจากฉันใช้บูสต์เป็นบูสเตอร์ STL มันจะโรยรอบ ๆ โค้ดของฉัน ห้องสมุดอื่น ๆ ที่ฉันใช้นั่นคือ PascalCase (SFML) สามารถบรรจุได้ง่ายขึ้นดังนั้นวิธีการใดก็ตามที่ได้รับนั้นค่อนข้างมาตรฐาน
สูงสุด

@ Pubby8: จากความอยากรู้: camelCase จะปะทะกับตัวประมวลผลก่อนได้อย่างไร
Joachim Sauer

@JoachimSauer แต่ละคำใน camelCase อาจมีตัวพิมพ์เล็ก แต่แมโครไม่สามารถเปลี่ยนตัวพิมพ์ สิ่งนี้จะกลายเป็นปัญหาหากคุณต้องการให้แมโครที่มีส่วนหนึ่งของคำเป็นอาร์กิวเมนต์คุณอาจต้องระบุทั้งสองกรณีเป็นอาร์กิวเมนต์: แมโคร (x, X) มันเป็นปัญหาเล็กน้อยที่น่าสนใจ แต่ควรทราบหากคุณต้องการใช้ตัวประมวลผลล่วงหน้า
Pubby

คำตอบ:


27

มีการประชุมสามัญสำหรับการโอนเป็นทุนที่ฉันควรรู้เกี่ยวกับอะไร?

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

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

อย่างไรก็ตามสิ่งที่คุณใช้กฎที่สำคัญที่สุดคือ: ให้สอดคล้อง!

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


ขอบคุณสำหรับข้อมูล ... ดังนั้นไลบรารีมาตรฐานจึงขีดเส้นใต้ใช่ไหม (อย่างน้อยก็มากกว่าสิ่งอื่นใด) ฉันคิดตามบรรทัดเหล่านั้น แต่มันก็ยากที่จะบอกเพราะสิ่งต่าง ๆ เช่น iostream ที่ชื่อวิธีครึ่งหนึ่งดูเหมือนจะเป็นชิ้นส่วนของคำศัพท์ที่เรียงซ้อนกันเหมือน ANSI C :-P
David Z

5
@David: ไลบรารี iostreams อาจอายุ 25 ปีและ (ยกเว้น C lib หรือแน่นอน) อาจเป็นส่วนที่เก่าแก่ที่สุดของ C ++ std lib หวังว่าไม่มีใครในใจที่ถูกต้องของพวกเขาจะออกแบบอย่างที่มันเป็นทุกวันนี้และหวังว่าแม้คนที่ไม่ได้อยู่ในใจที่เหมาะสมของพวกเขาจะไม่เลือกตัวระบุวิธีที่พวกเขาใช้ในห้องสมุดกระแสข้อมูล (C'mon มีฟังก์ชั่นการตั้งชื่อegptr, sputnและuflowเช่นเดียวกับunderflow. นั่นเป็นเพียงเฮฮา!) อย่างไรก็ตามใช่ lib มาตรฐานในปัจจุบันใช้ all_lowercase_with_underscores
sbi

@sbi ฉันพบว่าไลบรารี iostream จะไม่พิจารณาไลบรารีมาตรฐานสำหรับ C ++ อีกต่อไป และอย่างที่คุณพูดถึงตัวระบุมันไม่ได้มีประโยชน์ในฐานะที่เป็นแบบแผนการเขียนโปรแกรม ;-)
umlcat

2
@umlcat: ไลบรารี iostreams (ใน templatized จากที่ยอมรับสำหรับ C ++ 03) ถือเป็นส่วนหนึ่งของไลบรารีมาตรฐาน C ++
sbi

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

19

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

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

Early C ไม่มีค่าคงที่ดังนั้นค่าคงที่จึงต้องแสดงเป็นมาโคร ยิ่งไปกว่านั้นในวันแรก ๆ ของโปรแกรมนั้นสั้นกว่ามากเพื่อให้การปฏิบัติที่ไม่ดีในวันนี้สามารถนำมาใช้ได้ (เช่น IIRC Brian Kernighan เขียนโค้ดที่มีมาโครที่ไม่ใช่ตัวพิมพ์ใหญ่จำนวนมาก) และในสมัยนั้นคีย์บอร์ดที่ไม่มีตัวอักษรพิมพ์เล็กก็มีอยู่ ฉันใช้คอมพิวเตอร์ดังกล่าวบนคอมพิวเตอร์ Tandberg EC-10 ของนอร์เวย์ประมาณปี 1980 หรือ 1979 ฉันคิดว่ามันเป็น

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

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

ดังนั้น,

    int const answer = 42;    // Nice, good, OK.
    const int ANSWER = 0x2A;  // Ouch!
    #define COMPANYNAME_ANSWER 052  // Oh kill me, please.

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

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

ในขณะนี้ในปี 2011 C ++ มาตรฐานรองรับ Unicode ทั่วไปในชื่อ (และได้ทำมาตั้งแต่ปี 1998) ในขณะที่การใช้งาน C ++ ที่เกิดขึ้นจริงไม่ได้ โดยเฉพาะคอมไพเลอร์ g ++ เป็นตัวละครประจำชาติที่ถูกท้าทาย มันเกิดจากข้อ จำกัด ทางเทคโนโลยียุคมืด

ดังนั้น,

    double blueberryJamViscosity  = 0.0;    // OK
    double blåbærsyltetøyViskositet = 0.0;  // Ouch!

ในที่สุดในเรื่องของการขีดเส้นใต้กับตัวอักษรตัวพิมพ์ใหญ่สลับกัน

  • สำรองแบบฟอร์มที่จดจำได้ง่ายสำหรับชื่อประเภท
  • จองทั้งหมดที่เพิ่มขึ้นสำหรับมาโคร
  • คงเส้นคงวา.

ฉันคิดว่าเป็นเช่นนั้นจริงๆยกเว้นกฎอย่าง "โดยทั่วไปหลีกเลี่ยงชื่อตัวอักษรเดียวยกเว้น (ห่วง, เทมเพลต param, blah blah)" และ "หลีกเลี่ยงการใช้ l, สับสนได้ง่ายกับ 1" และ "หลีกเลี่ยงตัวพิมพ์ใหญ่ O, สับสนได้ง่าย กับ 0 " และแน่นอนว่าหลีกเลี่ยงการใช้ชื่อที่สงวนไว้เช่นเริ่มต้นด้วยเครื่องหมายขีดล่างตามด้วยตัวพิมพ์ใหญ่มีขีดล่างสองอันต่อเนื่องกันหรือเริ่มต้นด้วยเครื่องหมายขีดล่างและอยู่ในเนมสเปซส่วนกลาง

ไชโย


Alf, ISTR Stroustrup พูดถึงในการคัดลอกD&E C constจาก C ++ ดังนั้นสิ่งนี้จะต้องเกิดขึ้นนานแล้วและนานก่อนที่ Java อาจเป็น C89
sbi

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

2

ฉันมักจะยึดติดกับการประชุมที่ฉันเห็นมากที่สุดในฐานรหัสที่มีอยู่สำหรับภาษา ในกรณีของ C ++ ฉันมักจะเห็น camelCase ในกรณีของ Ruby หรือ PHP ฉันมักจะเห็น stuff_like_this

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


1

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

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


1

จากสิ่งที่ฉันเห็นมันแตกต่างกันระหว่างโครงการ

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

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


1

ฉันใช้ทั้งไลบรารีมาตรฐานและเพิ่มเป็นข้อมูลอ้างอิงสำหรับการตั้งชื่อการประชุม อย่างไรก็ตามมีปัญหากับวิธีนี้

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

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

ฉันพยายามไม่ใช้มาโคร อย่างไรก็ตามเมื่อฉันทำมาโครจะถูกสร้างให้ดูเหมือนฟังก์ชั่นเมื่อทำได้ ฉันยังใช้ค่า const หรือ enums แทนค่าคงที่ชัดแจ้งเพื่อหลีกเลี่ยงตัวพิมพ์ใหญ่ทั้งหมด ฉันมักจะนำหน้าสัญลักษณ์เหล่านี้ด้วย 'k' เพื่อระบุว่าพวกเขาคงที่

// instead of a manifest constant
#define HOURS 24

// use const
const int kHours = 24; 

// or enum
enum {
    kHours   = 24,
    kMinutes = 60
};

0

ข้อมูลอ้างอิงนี้อธิบายถึงรูปแบบการตั้งชื่อที่ค่อนข้างคล้ายกับรูปแบบที่ฉันเคยเห็นเคยประสบความสำเร็จใน บริษัท อย่างน้อยสามแห่งที่ฉันเคยทำมาก่อน

ตรงกันข้ามกับคำตอบก่อนหน้านี้ฉันจะหลีกเลี่ยงการปฏิบัติตามหลักการตั้งชื่อไลบรารี C ++ มาตรฐานในรหัสของฉันเองหากไม่มีเหตุผลอื่นนอกจากเพื่อหลีกเลี่ยงการชนชื่อกับไลบรารีมาตรฐาน

คำตอบ SO ก่อนหน้านี้ในหัวข้อที่เกี่ยวข้องอาจมีประโยชน์เช่นกัน: /programming/228783/what-are-the-rules-about-using-an-underscore-in-ac-identifier


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