Saya belajar cara memuat DLL secara dinamis, tetapi yang tidak saya mengerti adalah baris ini
typedef void (*FunctionFunc)();
Saya punya beberapa pertanyaan. Jika seseorang mampu menjawabnya, saya akan berterima kasih.
- Mengapa
typedef
digunakan? - Sintaksnya terlihat aneh; setelah itu
void
seharusnya tidak ada nama fungsi atau sesuatu? Sepertinya fungsi anonim. - Apakah pointer fungsi dibuat untuk menyimpan alamat memori suatu fungsi?
Jadi saya bingung saat ini; dapatkah kamu mengklarifikasi hal untukku?
using FunctionFunc = void (*)();
dapat digunakan sebagai gantinya. Ini sedikit lebih jelas bahwa Anda hanya mendeklarasikan nama untuk suatu tipe (penunjuk berfungsi)using FunctionFunc = void(void);
*
sedikit lebih eksplisit.Jawaban:
typedef
adalah konstruksi bahasa yang mengaitkan nama ke suatu jenis.Anda menggunakannya dengan cara yang sama Anda akan menggunakan jenis aslinya, misalnya
suka menggunakannya
Seperti yang Anda lihat, Anda bisa saja mengganti nama typedefed dengan definisi yang diberikan di atas.
Kesulitan terletak pada pointer ke fungsi sintaksis dan keterbacaan dalam C dan C ++, dan
typedef
dapat meningkatkan pembacaan deklarasi tersebut. Namun, sintaksinya sesuai, karena fungsi - tidak seperti tipe yang lebih sederhana - mungkin memiliki nilai dan parameter pengembalian, sehingga deklarasi pointer ke fungsi terkadang panjang dan kompleks.Keterbacaan dapat mulai sangat rumit dengan pointer ke array fungsi, dan beberapa rasa lain yang bahkan lebih tidak langsung.
Untuk menjawab tiga pertanyaan Anda
Mengapa typedef digunakan? Untuk memudahkan pembacaan kode - terutama untuk pointer ke fungsi, atau struktur nama.
Sintaksnya terlihat aneh (dalam pointer ke pernyataan fungsi) Sintaks itu tidak jelas untuk dibaca, setidaknya ketika mulai.
typedef
Sebaliknya, menggunakan deklarasi memudahkan pembacaanApakah pointer fungsi dibuat untuk menyimpan alamat memori suatu fungsi? Ya, pointer fungsi menyimpan alamat suatu fungsi. Ini tidak ada hubungannya dengan
typedef
konstruk yang hanya memudahkan penulisan / pembacaan suatu program; kompiler hanya perlu memperluas definisi typedef sebelum mengkompilasi kode aktual.Contoh:
sumber
typedef type alias
tetapi dengan pointer fungsi tampaknya hanya ada 2 argumentypedef type
,. Apakah alias default ke nama yang ditentukan dalam tipe argumen?square
dan&square
(dan, memang,*square
dan**square
) semuanya merujuk ke pointer fungsi yang sama.typedef int newname
, Anda membuatnewname
alias untukint
. Dengantypedef int (*func)(int)
, Anda membuatfunc
alias untukint (*)(int)
- pointer berfungsi mengambilint
argumen dan mengembalikanint
nilai.int (*func)(int)
, saya mengerti bahwa func adalah alias, hanya sedikit bingung karena alias kusut dengan tipenya. Pergi dengantypedef int INT
sebagai contoh saya akan lebih kemudahan jika typedef fungsi pointer adalah bentuktypedef int(*function)(int) FUNC_1
. Dengan begitu saya bisa melihat tipe dan alias dalam dua token yang terpisah daripada disatukan menjadi satu.typedef
digunakan untuk mengetik alias; dalam hal ini Anda aliasingFunctionFunc
untukvoid(*)()
.Memang sintaksnya memang terlihat aneh, lihat ini:
Tidak, ini hanya memberitahu kompiler bahwa
FunctionFunc
tipe akan menjadi pointer fungsi, itu tidak mendefinisikan satu, seperti ini:sumber
typedef
tidak tidak menyatakan jenis baru. Anda dapat memiliki banyaktypedef
nama yang ditentukan dari jenis yang sama, dan mereka tidak berbeda (mis. wrt. overloading fungsi). ada beberapa keadaan di mana, sehubungan dengan bagaimana Anda dapat menggunakan nama, nama yangtypedef
didefinisikan tidak persis sama dengan apa yang didefinisikan, tetapi beberapatypedef
nama yang ditetapkan untuk hal yang sama, adalah setara.Tanpa
typedef
kata, dalam C ++ deklarasi akan mendeklarasikan variabelFunctionFunc
pointer tipe berfungsi tanpa argumen, kembalivoid
.Dengan
typedef
itu alih-alih mendefinisikanFunctionFunc
sebagai nama untuk tipe itu.sumber
Jika Anda dapat menggunakan C ++ 11, Anda mungkin ingin menggunakan
std::function
danusing
kata kunci.sumber
using
kata kunci C ++ 11 akan sepertitypedef std::function<void(int, std::string)> FunctionFunc;
, kalau-kalau seseorang ingin pembungkus lain di sekitar fungsi tanpa C ++ 11sumber
typedef (*double) p
, apakah '&' opsional?typedef double* p
untuk menentukan pointer ke ganda. Jika Anda ingin mengisip
pointer dari variabel primitif, Anda harus menggunakan tanda '&'. Sebagai catatan, kami Anda * <nama pointer> untuk dereference pointer. The*
digunakan dalam fungsi pointer dereference pointer (nama fungsi) dan pergi ke blok memori di mana instruksi fungsi berada.Untuk kasus umum sintaks Anda dapat melihat lampiran A dari standar ANSI C .
Dalam bentuk Backus-Naur dari sana, Anda bisa melihat yang
typedef
memiliki tipestorage-class-specifier
.Pada tipe yang
declaration-specifiers
Anda dapat melihat bahwa Anda dapat mencampur banyak tipe specifier, urutan yang tidak masalah.Misalnya, benar untuk mengatakan,
untuk menentukan jenis
a
sebagai alias untuklong long
. Jadi, untuk memahami typedef pada penggunaan lengkap, Anda perlu berkonsultasi dengan beberapa bentuk backus-naur yang mendefinisikan sintaks (ada banyak tata bahasa yang benar untuk ANSI C, tidak hanya yang dari ISO).Saat Anda menggunakan typedef untuk mendefinisikan alias untuk jenis fungsi, Anda harus meletakkan alias di tempat yang sama tempat Anda meletakkan pengenal fungsi. Dalam kasus Anda, Anda mendefinisikan tipe
FunctionFunc
sebagai alias untuk penunjuk yang berfungsi yang pemeriksaan tipenya dinonaktifkan saat panggilan berlangsung dan tidak mengembalikan apa pun.sumber