พื้นหลัง
คำสั่งประกาศตัวแปรใน C ประกอบด้วยสามส่วนคือชื่อของตัวแปรมันพิมพ์ฐานและปรับปรุงประเภท (s)
การดัดแปลงประเภทมีสามประเภท:
- ตัวชี้*(คำนำหน้า)
- Array [N](postfix)
- ฟังก์ชั่น()(postfix)- คุณสามารถระบุรายการอาร์กิวเมนต์ของฟังก์ชันภายใน parens แต่เพื่อความท้าทายนี้เราจะเพิกเฉยและลองใช้()(ซึ่งในทางเทคนิคหมายถึง "ฟังก์ชันสามารถใช้อาร์กิวเมนต์ชนิดใดก็ได้")
 
- คุณสามารถระบุรายการอาร์กิวเมนต์ของฟังก์ชันภายใน parens แต่เพื่อความท้าทายนี้เราจะเพิกเฉยและลองใช้
และวิธีในการอ่านเครื่องหมายเป็นดังนี้:
int i;             // i is an int
float *f;          // f is a pointer to a float
my_struct_t s[10]; // s is an array of 10 my_struct_t
int func();        // func is a function returning an int
สิ่งที่จับได้คือเราสามารถผสมสิ่งเหล่านี้เพื่อสร้างรูปแบบที่ซับซ้อนมากขึ้นเช่นอาร์เรย์ของอาร์เรย์หรืออาร์เรย์ของพอยน์เตอร์ของฟังก์ชันหรือตัวชี้ไปยังอาร์เรย์ของพอยน์เตอร์ :
int arr[3][4];
// arr is an array of 3 arrays of 4 ints
int (*fptrs[10])();
// fptrs is an array of 10 pointers to functions returning an int
float *(*p)[16];
// p is a pointer to an array of 16 pointers to float
ฉันอ่านข้อความที่ซับซ้อนเหล่านี้ได้อย่างไร
- เริ่มจากชื่อตัวแปร (name) is ...
- เลือกตัวดัดแปลงที่มีลำดับความสำคัญสูงสุด
- อ่านมัน:
- * -> pointer to ...
- [N] -> array of N ...
- () -> function returning ...
 
- ทำซ้ำ 2 และ 3 จนกระทั่งโมดิฟายเออร์หมด
- ในที่สุดอ่านประเภทฐาน ... (base type).
ใน C ตัวดำเนินการ postfix จะมีความสำคัญเหนือตัวดำเนินการส่วนนำหน้าและตัวดัดแปลงชนิดจะไม่มีข้อยกเว้น ดังนั้น[]และผูกแรกแล้ว() *อะไรก็ตามที่อยู่ในคู่ของ parens (...)(เพื่อไม่ให้สับสนกับโอเปอเรเตอร์ฟังก์ชั่น) จะผูกสิ่งแรกไว้ข้างนอก
ตัวอย่างที่แสดง:
int (*fptrs[10])();
      fptrs           fptrs is ...
           [10]       array of 10 ... // [] takes precedence over *
    (*         )      pointer to ...
                ()    function returning ...
int                   int
งาน
ให้บรรทัดของคำแถลงการประกาศตัวแปรที่เขียนใน C เอาท์พุทนิพจน์ภาษาอังกฤษที่อธิบายบรรทัดโดยใช้วิธีการที่แสดงด้านบน
อินพุต
อินพุตเป็นคำสั่ง C เดียวที่มีชนิดฐานเดียวชื่อตัวแปรเดี่ยวตัวดัดแปลงชนิดศูนย์หรือมากกว่าและเซมิโคลอนลงท้าย คุณต้องใช้องค์ประกอบไวยากรณ์ทั้งหมดที่กล่าวถึงข้างต้นรวมถึง:
- [A-Za-z_][A-Za-z0-9_]*ทั้งพิมพ์ฐานและชื่อตัวแปรตรงกับการแสดงออกปกติ
- ตามทฤษฎีแล้วโปรแกรมของคุณควรรองรับตัวดัดแปลงประเภทไม่ จำกัด จำนวน
คุณสามารถทำให้องค์ประกอบไวยากรณ์ C อื่น ๆ ง่ายขึ้นด้วยวิธีต่อไปนี้ (ยินดีต้อนรับการใช้งานอย่างเต็มรูปแบบ)
- ประเภทฐานอยู่เสมอคำเดียวเช่นint,float, ,uint32_tmyStructบางอย่างเช่นunsigned long longจะไม่ถูกทดสอบ
- สำหรับโน้ตอาร์เรย์[N]จำนวนNมักจะเป็นจำนวนเต็มบวกเดียวเขียนในฐาน 10. สิ่งที่ชอบint a[5+5],int a[SIZE]หรือint a[0x0f]จะไม่ได้รับการทดสอบ
- สำหรับสัญกรณ์ฟังก์ชั่น()จะไม่มีการระบุพารามิเตอร์เลยตามที่กล่าวไว้ข้างต้น
- สำหรับช่องว่าง0x20จะใช้อักขระช่องว่างเท่านั้น คุณสามารถ จำกัด โปรแกรมของคุณเฉพาะการใช้งานช่องว่างเช่น- ใช้เพียงหนึ่งช่องว่างหลังจากประเภทฐาน
- ใช้ช่องว่างทุกที่ระหว่างโทเค็น
 
- อย่างไรก็ตามคุณไม่สามารถใช้ช่องว่างต่อเนื่องตั้งแต่สองจุดขึ้นไปเพื่อถ่ายทอดข้อมูลมากกว่าการเป็นตัวคั่นโทเค็น
ตามไวยากรณ์ C ชุดค่าผสมสามชุดต่อไปนี้ไม่ถูกต้องและจะไม่ถูกทดสอบ:
- f()()ฟังก์ชันส่งคืนฟังก์ชัน
- f()[]ฟังก์ชันส่งคืนอาร์เรย์
- a[]()ฟังก์ชัน Array of N
นักพัฒนา C ใช้แบบฟอร์มที่เทียบเท่าเหล่านี้แทน (และสิ่งเหล่านี้ครอบคลุมในกรณีทดสอบ):
- (*f())()ฟังก์ชันส่งคืนตัวชี้ไปยังฟังก์ชัน
- *f()ฟังก์ชันส่งกลับตัวชี้ไปที่องค์ประกอบแรกของอาร์เรย์
- (*a[])()Array of N พอยน์เตอร์ที่ใช้งานได้
เอาท์พุต
ผลลัพธ์เป็นประโยคภาษาอังกฤษเดียว คุณไม่จำเป็นต้อง (แต่คุณสามารถทำได้หากต้องการ) เคารพไวยากรณ์ภาษาอังกฤษเช่นการใช้a, an, theแบบฟอร์มเอกพจน์ / พหูพจน์และจุดสิ้นสุด (จุด) แต่ละคำควรคั่นด้วยช่องว่างอย่างน้อยหนึ่งช่องว่าง (เว้นวรรคแท็บขึ้นบรรทัดใหม่) ดังนั้นผลลัพธ์จะอ่านได้โดยมนุษย์
อีกครั้งนี่คือกระบวนการแปลง:
- เริ่มจากชื่อตัวแปร (name) is ...
- เลือกตัวดัดแปลงที่มีลำดับความสำคัญสูงสุด
- อ่านมัน:
- * -> pointer to ...
- [N] -> array of N ...
- () -> function returning ...
 
- ทำซ้ำ 2 และ 3 จนกระทั่งโมดิฟายเออร์หมด
- ในที่สุดอ่านประเภทฐาน ... (base type).
กรณีทดสอบ
int i;              // i is int
float *f;           // f is pointer to float
my_struct_t s[10];  // s is array of 10 my_struct_t
int func();         // func is function returning int
int arr[3][4];      // arr is array of 3 array of 4 int
int (*fptrs[10])(); // fptrs is array of 10 pointer to function returning int
float *(*p)[16];    // p is pointer to array of 16 pointer to float
_RANdom_TYPE_123 (**(*_WTH_is_TH15)())[1234][567];
/* _WTH_is_TH15 is pointer to function returning pointer to pointer to array of
   1234 array of 567 _RANdom_TYPE_123 */
uint32_t **(*(**(*(***p)[2])())[123])[4][5];
/* p is pointer to pointer to pointer to array of 2 pointer to function returning
   pointer to pointer to array of 123 pointer to array of 4 array of 5 pointer to
   pointer to uint32_t */
uint32_t (**((*(**(((*(((**(*p)))[2]))())))[123])[4])[5]);
// Same as above, just more redundant parens
some_type (*(*(*(*(*curried_func())())())())())();
/* curried_func is function returning pointer to function returning pointer to
   function returning pointer to function returning pointer to
   function returning pointer to function returning some_type */
เกณฑ์การให้คะแนนและการชนะ
นี่คือความท้าทายรหัส - กอล์ฟ โปรแกรมที่มีจำนวนไบต์น้อยที่สุดจะเป็นผู้ชนะ
int arr[3][4];คือan array of 3 arrays of 4 ints(ตามที่คุณพูด) หรือan array of 4 arrays of 3 ints?
                ;จุดสิ้นสุดของบรรทัดหรือไม่?