Latar Belakang
Pernyataan deklarasi variabel dalam C terdiri dari tiga bagian: nama variabel, tipe dasarnya , dan tipe pengubah .
Ada tiga jenis pengubah tipe:
- Pointer
*
(awalan) - Array
[N]
(postfix) - Fungsi
()
(postfix)- Anda dapat menentukan daftar argumen fungsi di dalam parens, tetapi untuk tantangan ini, mari kita abaikan dan gunakan saja
()
(yang secara teknis berarti "fungsi dapat mengambil segala jenis argumen").
- Anda dapat menentukan daftar argumen fungsi di dalam parens, tetapi untuk tantangan ini, mari kita abaikan dan gunakan saja
Dan cara membaca notasi adalah sebagai berikut:
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
Tangkapannya adalah kita dapat menggabungkan semua ini untuk membentuk tipe yang lebih rumit, seperti array array atau array fungsi pointer atau pointer ke array pointer :
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
Bagaimana saya membaca pernyataan rumit ini?
- Mulai dari nama variabel.
(name) is ...
- Pilih pengubah dengan prioritas tertinggi.
- Membacanya:
* -> pointer to ...
[N] -> array of N ...
() -> function returning ...
- Ulangi 2 dan 3 sampai pengubah habis.
- Terakhir, baca tipe dasar.
... (base type).
Dalam C, operator postfix didahulukan dari pada operator prefix, dan pengubah tipe tidak terkecuali. Karena itu, []
dan ()
ikat terlebih dahulu, lalu *
. Apa pun di dalam sepasang parens (...)
(jangan dikelirukan dengan operator fungsi) mengikat pertama di atas apa pun di luar.
Contoh ilustrasi:
int (*fptrs[10])();
fptrs fptrs is ...
[10] array of 10 ... // [] takes precedence over *
(* ) pointer to ...
() function returning ...
int int
Tugas
Diberikan garis pernyataan deklarasi variabel yang ditulis dalam C, output ekspresi bahasa Inggris yang menggambarkan garis, menggunakan metode yang ditunjukkan di atas.
Memasukkan
Input adalah pernyataan C tunggal yang mencakup jenis basis tunggal, nama variabel tunggal, nol atau lebih jenis pengubah dan titik koma akhir. Anda harus menerapkan semua elemen sintaks yang dibahas di atas, ditambah:
- Baik tipe dasar dan nama variabel cocok dengan ekspresi reguler
[A-Za-z_][A-Za-z0-9_]*
. - Secara teoritis, program Anda harus mendukung pengubah tipe dalam jumlah tidak terbatas.
Anda dapat menyederhanakan elemen sintaks C lainnya dengan cara berikut (implementasi penuh juga diterima):
- Jenis dasar selalu satu kata, misalnya
int
,float
,uint32_t
,myStruct
. Sesuatu sepertiunsigned long long
tidak akan diuji. - Untuk notasi array
[N]
, angkaN
akan selalu berupa bilangan bulat positif tunggal yang ditulis dalam basis 10. Hal-hal sepertiint a[5+5]
,int a[SIZE]
atauint a[0x0f]
tidak akan diuji. - Untuk notasi fungsi
()
, tidak ada parameter yang ditentukan sama sekali, seperti yang ditunjukkan di atas. - Untuk spasi putih, hanya karakter spasi yang
0x20
akan digunakan. Anda dapat membatasi program Anda untuk penggunaan spasi putih tertentu, misalnya- Gunakan hanya satu spasi setelah tipe dasar
- Gunakan ruang di mana-mana di antara token
- Namun, Anda tidak dapat menggunakan dua atau lebih spasi berturut-turut untuk menyampaikan lebih banyak informasi daripada menjadi pemisah token.
Menurut sintaks C, tiga kombinasi berikut tidak valid, dan karenanya tidak akan diuji:
f()()
Fungsi mengembalikan fungsif()[]
Berfungsi mengembalikan arraya[]()
Array fungsi N
Pengembang C menggunakan formulir yang setara ini sebagai gantinya (dan semua ini tercakup dalam kasus uji):
(*f())()
Fungsi mengembalikan pointer ke fungsi*f()
Fungsi mengembalikan pointer ke elemen pertama array(*a[])()
Array N pointer berfungsi
Keluaran
Outputnya adalah satu kalimat bahasa Inggris. Anda tidak perlu (tetapi Anda bisa jika mau) menghormati tata bahasa Inggris, misalnya penggunaan a, an, the
, bentuk tunggal / jamak, dan titik akhir (titik). Setiap kata harus dipisahkan oleh satu atau lebih spasi putih (spasi, tab, baris baru) sehingga hasilnya dapat dibaca oleh manusia.
Sekali lagi, inilah proses konversi:
- Mulai dari nama variabel.
(name) is ...
- Pilih pengubah dengan prioritas tertinggi.
- Membacanya:
* -> pointer to ...
[N] -> array of N ...
() -> function returning ...
- Ulangi 2 dan 3 sampai pengubah habis.
- Terakhir, baca tipe dasar.
... (base type).
Uji kasus
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 */
Kriteria Penilaian & Menang
Ini adalah tantangan kode-golf . Program dengan jumlah byte terkecil menang.
int arr[3][4];
adalah an array of 3 arrays of 4 ints
(seperti yang Anda katakan), atau an array of 4 arrays of 3 ints
?
;
di akhir baris?