จุดประสงค์ของ [1] นี้ในตอนท้ายของการประกาศโครงสร้างคืออะไร?


96

ฉันกำลังสอดแนมไฟล์ส่วนหัวของไมโครคอนโทรลเลอร์ MSP430 ของฉันและฉันพบสิ่งนี้ใน<setjmp.h>:

/* r3 does not have to be saved */
typedef struct
{
    uint32_t __j_pc; /* return address */
    uint32_t __j_sp; /* r1 stack pointer */
    uint32_t __j_sr; /* r2 status register */
    uint32_t __j_r4;
    uint32_t __j_r5;
    uint32_t __j_r6;
    uint32_t __j_r7;
    uint32_t __j_r8;
    uint32_t __j_r9;
    uint32_t __j_r10;
    uint32_t __j_r11;
} jmp_buf[1]; /* size = 20 bytes */

ฉันเข้าใจว่ามันประกาศโครงสร้างที่ไม่ระบุตัวตนและ typedef เป็นของมันjmp_bufแต่ฉันไม่สามารถเข้าใจได้ว่า[1]มีไว้เพื่ออะไร ฉันรู้ว่ามันประกาศว่าjmp_bufเป็นอาร์เรย์ที่มีสมาชิกหนึ่งตัว (ของโครงสร้างที่ไม่ระบุตัวตนนี้) แต่ฉันนึกไม่ออกว่ามันใช้ทำอะไร ความคิดใด ๆ ?


5
จะทำอย่างไรกับการสลายตัวเป็นตัวชี้?
Elazar

3
ความคิดเห็นสุดท้ายดูเหมือนผิดอย่างสิ้นเชิง ...
R .. GitHub STOP HELPING ICE

คำตอบ:


117

นี่เป็นเคล็ดลับทั่วไปในการสร้าง "ประเภทการอ้างอิง" ใน C ซึ่งการใช้มันเป็นอาร์กิวเมนต์ของฟังก์ชันทำให้อาร์เรย์องค์ประกอบเดียวลดระดับตัวชี้ไปยังองค์ประกอบแรกโดยที่โปรแกรมเมอร์ไม่จำเป็นต้องใช้ตัว&ดำเนินการอย่างชัดเจนเพื่อรับที่อยู่ ในกรณีที่ประกาศเป็นประเภทสแต็กจริง (ไม่จำเป็นต้องมีการจัดสรรแบบไดนามิก) แต่เมื่อส่งผ่านเป็นอาร์กิวเมนต์ฟังก์ชันที่เรียกว่าจะได้รับตัวชี้ไม่ใช่สำเนาดังนั้นจึงถูกส่งผ่านไปในราคาถูก (และสามารถกลายพันธุ์ได้โดยฟังก์ชันที่เรียกว่าถ้าไม่const).

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


12
นอกจากนี้ยังป้องกันการคัดลอกผ่าน=ไฟล์.
melpomene

11
นั่นเป็นขั้นต้น ฉันจะยอมรับคำตอบนี้เมื่อเวลาผ่านไปขั้นต่ำ ขอบคุณสำหรับความช่วยเหลือของคุณ!
Alexander - คืนสถานะ Monica

3
@ อเล็กซานเดอร์: มันไม่ได้แย่มากนักเมื่อห่อหุ้มด้วยสิ่งtypedefนี้ ใช่การทำแบบเฉพาะกิจนี้จะแย่มาก แต่ถ้าคุณมีประเภททึบแสงเล็กน้อยโดยที่ผู้ใช้ API ไม่จำเป็นต้องคิดเกี่ยวกับการอ้างอิงเทียบกับความหมายที่ไม่ใช่การอ้างอิง (ควรผ่านการอ้างอิงเสมอ ) เป็นวิธีที่สมเหตุสมผล ของการเพิ่มความหมายการอ้างอิงอัตโนมัติให้กับภาษาที่ไม่มีมัน แม้จะใช้งานได้หากผู้ใช้เขียน API ของตนเองที่ได้รับประเภทเนื่องจากใน C การประกาศว่าคุณยอมรับอาร์เรย์เป็นอาร์กิวเมนต์หมายความว่าคุณยอมรับตัวชี้ ทุกอย่าง "ใช้ได้ผล"
ShadowRanger

4
@ShadowRanger เป็นเคล็ดลับที่ชาญฉลาด แต่... otherwise lacks itสิ่งที่น่ากลัวเกี่ยวกับเรื่องนี้ ข้อ จำกัด ของ C ไม่ใช่วิธีแก้ปัญหาเอง
Alexander - Reinstate Monica

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