ทำไมต้องใช้ typedefs สำหรับ structs


12

ใน C (ANSI, C99 ฯลฯ ) structs อาศัยอยู่ในเนมสเปซของตนเอง struct สำหรับรายการที่เชื่อมโยงอาจมีลักษณะเช่นนี้:

struct my_buffer_type {
   struct my_buffer_type * next;
   struct my_buffer_type * prev;
   void * data;
};

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

typedef struct tag_buffer_type {
   struct tag_buffer_type * next;
   struct tag_buffer_type * prev;
   void * data;
} my_buffer_type;

และจากนั้นอ้างอิง struct get_next_element(my_buffer_type * ptr)เช่นประเภทปกติคือ

ตอนนี้คำถามของฉันคือ: มีเหตุผลเฉพาะสำหรับเรื่องนี้?

Wikipedia พูดว่าhttp://en.wikipedia.org/wiki/Typedef#Usage_concerns

บางคนตรงข้ามกับการใช้ typedefs อย่างกว้างขวาง ข้อโต้แย้งส่วนใหญ่มุ่งเน้นที่แนวคิดที่ typedefs เพียงแค่ซ่อนชนิดข้อมูลจริงของตัวแปร ตัวอย่างเช่น Greg Kroah-Hartman แฮกเกอร์เคอร์เนลและตัวจัดการลีนุกซ์ไม่สนับสนุนการใช้สิ่งใดนอกจากการประกาศฟังก์ชันต้นแบบ เขาให้เหตุผลว่าการฝึกฝนนี้ไม่เพียง แต่ทำให้โค้ดยุ่งเหยิงโดยไม่จำเป็นเท่านั้น แต่ยังสามารถทำให้โปรแกรมเมอร์เขียนผิดโครงสร้างขนาดใหญ่ที่คิดว่าเป็นประเภทง่าย ๆ โดยไม่ตั้งใจได้ [4]

คนอื่น ๆ ยืนยันว่าการใช้ typedefs สามารถทำให้การบำรุงรักษาโค้ดง่าย K&R ระบุว่ามีสองเหตุผลในการใช้ typedef อันดับแรกให้วิธีในการทำให้โปรแกรมพกพาได้มากขึ้น แทนที่จะต้องเปลี่ยนประเภททุกที่ที่ปรากฏในไฟล์ต้นฉบับของโปรแกรมจะต้องเปลี่ยนคำสั่ง typedef เพียงคำเดียว ประการที่สอง typedef สามารถทำให้การประกาศที่ซับซ้อนเข้าใจง่ายขึ้น

ฉันเองสงสัยว่ามีประโยชน์ไม่เพียงพอที่จะมีstructnamespace แยกต่างหากบางครั้งไม่ใช้ typedef'd structs และเนื่องจากมีวัฒนธรรมการเขียนโปรแกรม C หลาย ๆ รอบ (การเขียนโปรแกรม Windows C มีประเพณีที่แตกต่างจากการเขียนโปรแกรม Linux C ในประสบการณ์ของฉัน) ประเพณีที่ฉันไม่รู้

จากนั้นฉันสนใจการพิจารณาทางประวัติศาสตร์ (รุ่นก่อนรุ่น C แรก)


4
วัตถุประสงค์ของการtypedef คือการซ่อนชนิดของตัวแปรที่แท้จริง ใช้time_tเป็นตัวอย่าง: ถ้าคนไปรอบ ๆ โดยใช้ชนิดจำนวนเต็มพื้นฐานการเปลี่ยนแปลงในการดำเนินการดังกล่าวเป็นคนที่จะต้องอยู่ใน 2038 จะทำลายมากอันยิ่งใหญ่ของรหัส หากคนใช้โครงสร้างโดยไม่เข้าใจว่าเป็นความผิดพลาดของโปรแกรมเมอร์ไม่ใช่สิ่งก่อสร้าง
Blrfl

คำตอบ:


14

ฉันทำงานในโครงการขนาดใหญ่ที่ใช้ typedef'd structs อย่างกว้างขวาง เราทำเช่นนั้นด้วยเหตุผลสองประการ โปรดทราบว่านี่คือการแยกล่วงหน้า C99 และเนมสเปซ

  1. มันง่ายกว่าที่จะพิมพ์my_buffer_type *bufferแทนstruct tag_buffer_type *bufferและสำหรับขนาดของ codebase (1M + loc) ที่สร้างความแตกต่างอย่างมาก

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

    • ฉันคิดว่านี่เป็นความขัดแย้งโดยตรงกับข้อความอ้างอิงจาก Greg Kroah-Hartman ที่คุณให้ไว้ FWIW โครงการนั้นเป็นแอปพลิเคชันไคลเอนต์ / เซิร์ฟเวอร์ไม่ใช่เคอร์เนลดังนั้นจึงมีข้อควรพิจารณาที่แตกต่างกันในการพิจารณา
  3. การรักษาโครงสร้างเป็นวัตถุทำให้เราสามารถห่อหุ้มข้อมูลได้ดีขึ้น การตรวจสอบโค้ดพบว่ามีบางสถานการณ์ที่ผู้พัฒนารายใหม่จะละเมิดหลักการของการห่อหุ้มที่เราใช้ การใช้ typedef'd structs ทำให้การละเมิดเหล่านั้นชัดเจนจริงๆ

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


5

ทุกครั้งแทนที่จะพิมพ์

struct my_buffer_type *buffer;

ถ้าคุณtypedefคุณสามารถใช้โดยตรง

my_buffer_type *buffer;

typedefหลักของ usege คือการลดจำนวนการกดแป้นที่จำเป็นในการเขียนรหัสและเพื่อเพิ่มความสามารถในการอ่าน


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