ฉันเจอรหัสที่มีสิ่งต่อไปนี้:
struct ABC {
unsigned long array[MAX];
} abc;
เมื่อใดจึงควรใช้คำประกาศเช่นนี้
ฉันเจอรหัสที่มีสิ่งต่อไปนี้:
struct ABC {
unsigned long array[MAX];
} abc;
เมื่อใดจึงควรใช้คำประกาศเช่นนี้
คำตอบ:
ช่วยให้คุณสามารถส่งอาร์เรย์ไปยังฟังก์ชันตามค่าหรือส่งคืนเป็นค่าจากฟังก์ชัน
โครงสร้างสามารถส่งผ่านค่าได้ซึ่งแตกต่างจากอาร์เรย์ที่สลายตัวเป็นตัวชี้ในบริบทเหล่านี้
ข้อดีอีกประการหนึ่งคือมันแยกขนาดออกไปดังนั้นคุณจึงไม่ต้องใช้[MAX]
โค้ดทั้งหมดของคุณในทุกที่ที่คุณประกาศวัตถุดังกล่าว สิ่งนี้สามารถทำได้ด้วย
typedef char ABC[MAX];
แต่คุณมีปัญหาที่ใหญ่กว่ามาก: คุณต้องระวังว่าABC
เป็นประเภทอาร์เรย์ (แม้ว่าคุณจะไม่เห็นสิ่งนี้เมื่อคุณประกาศตัวแปรประเภทABC
) มิฉะนั้นคุณจะถูกต่อยจากข้อเท็จจริงที่ว่าABC
จะมีความหมายแตกต่างออกไป ในรายการอาร์กิวเมนต์ของฟังก์ชันเทียบกับการประกาศ / นิยามตัวแปร
ข้อดีอีกอย่างหนึ่งคือโครงสร้างช่วยให้คุณสามารถเพิ่มองค์ประกอบเพิ่มเติมได้ในภายหลังหากคุณต้องการโดยไม่ต้องเขียนโค้ดซ้ำ
คุณสามารถคัดลอกโครงสร้างและส่งคืนโครงสร้างจากฟังก์ชัน
คุณไม่สามารถทำได้ด้วยอาร์เรย์ - เว้นแต่จะเป็นส่วนหนึ่งของโครงสร้าง!
ลอกแบบนี้ก็ได้
struct ABC a, b;
........
a = b;
สำหรับอาร์เรย์คุณจะต้องใช้ฟังก์ชันmemcpyหรือลูปเพื่อกำหนดแต่ละองค์ประกอบ
คุณสามารถใช้ struct เพื่อให้เป็นชนิดใหม่ของข้อมูลเช่นสตริง คุณสามารถกำหนด:
struct String {
char Char[MAX];
};
หรือคุณสามารถสร้างรายการข้อมูลที่คุณสามารถใช้โดยการโต้แย้งของฟังก์ชันหรือส่งคืนในวิธีการของคุณ โครงสร้างมีความยืดหยุ่นมากกว่าอาร์เรย์เนื่องจากสามารถรองรับตัวดำเนินการบางอย่างเช่น = และคุณสามารถกำหนดวิธีการบางอย่างได้
หวังว่าจะเป็นประโยชน์สำหรับคุณ :)
ข้อดีอีกประการหนึ่งของการใช้ a ดังกล่าวstruct
คือการบังคับใช้ความปลอดภัยในทุกที่ที่ใช้เช่นstruct
นั้น โดยเฉพาะอย่างยิ่งถ้าคุณมีอาร์เรย์สองประเภทที่ประกอบด้วยอาร์เรย์ที่มีขนาดเท่ากันซึ่งใช้เพื่อวัตถุประสงค์ที่แตกต่างกันประเภทเหล่านี้จะช่วยให้คุณหลีกเลี่ยงการใช้อาร์เรย์อย่างไม่เหมาะสมโดยไม่ได้ตั้งใจ
หากคุณไม่รวมอาร์เรย์ไว้ใน a struct
คุณยังสามารถประกาศ a typedef
ได้ซึ่งมีข้อดีบางประการของstruct
- •ประเภทจะถูกประกาศเพียงครั้งเดียวขนาดจะถูกต้องโดยอัตโนมัติ•เจตนาของรหัสจะชัดเจนขึ้น• และรหัสสามารถดูแลรักษาได้มากกว่า - แต่คุณสูญเสีย◦ความปลอดภัยของประเภทที่เข้มงวด◦ความสามารถในการคัดลอกและส่งคืนค่าของประเภทและ◦ความสามารถในการเพิ่มสมาชิกในภายหลังโดยไม่ทำลายส่วนที่เหลือของรหัส สองtypedef
s สำหรับอาร์เรย์เปล่าของประเภทที่ระบุจะให้ผลเฉพาะประเภทที่แตกต่างกันหากมีขนาดต่างกัน ยิ่งไปกว่านั้นหากคุณใช้typedef
โดยไม่มี*
ในอาร์กิวเมนต์ฟังก์ชันจะเทียบเท่ากับchar *
การลดความปลอดภัยของประเภทลงอย่างมาก
โดยสรุป :
typedef struct A_s_s { char m[113]; } A_s_t; // Full type safey, assignable
typedef char A_c_t[113]; // Partial type-safety, not assignable
A_s_t v_s(void); // Allowed
A_c_t v_c(void); // Forbidden
void s__v(A_s_t); // Type-safe, pass by value
void sP_v(A_s_t *); // Type-safe
void c__v(A_c_t); // UNSAFE, just means char * (GRRR!)
void cP_v(A_c_t *); // SEMI-safe, accepts any array of 113
โครงสร้างสามารถมีฟังก์ชันการเริ่มต้นอาร์เรย์คัดลอกและฟินิซึ่งเลียนแบบข้อดีบางประการของกระบวนทัศน์การจัดการหน่วยความจำ OOP ในความเป็นจริงมันง่ายมากที่จะขยายแนวคิดนี้ในการเขียนยูทิลิตี้การจัดการหน่วยความจำทั่วไป (โดยใช้โครงสร้าง sizeof () เพื่อให้ทราบว่ามีการจัดการกี่ไบต์) เพื่อจัดการโครงสร้างที่ผู้ใช้กำหนดเอง ฐานรหัสการผลิตอัจฉริยะจำนวนมากที่เขียนด้วย C ใช้สิ่งเหล่านี้อย่างหนักและโดยทั่วไปจะไม่ใช้อาร์เรย์เว้นแต่ขอบเขตจะอยู่ในพื้นที่มาก
ในความเป็นจริงสำหรับอาร์เรย์ที่ฝังอยู่ในโครงสร้างคุณสามารถทำ "สิ่งที่ชาญฉลาด" อื่น ๆ เช่นการตรวจสอบขอบเขตเมื่อใดก็ตามที่คุณต้องการเข้าถึงอาร์เรย์นี้ อีกครั้งเว้นแต่ขอบเขตอาร์เรย์จะ จำกัด มากควรใช้และส่งต่อข้อมูลข้ามโปรแกรมต่างๆ ไม่ช้าก็เร็วคุณจะพบกับโรคจิตที่จะทำให้คุณตื่นในตอนกลางคืนและทำลายวันหยุดสุดสัปดาห์
struct
ที่มีเพียงอาร์เรย์