Saya punya PIC18F46K22 dan memprogramnya dengan kompiler XC8. Pada akhirnya, saya akan memiliki sistem seperti komputer dengan stdin
dan stdout
. Jadi di loop utama akan ada fungsi yang memeriksa apakah ada input baru. Jika ada input, fungsi akan dipanggil sesuai. Jadi misalnya ketika saya masukan A pada stdin
, PIC akan menjalankan fungsi seperti function_A
bukan function_B
yang disebut ketika saya input B.
Ketika PIC selesai dengan fungsi, saya ingin input baru dikirim ke fungsi. Jadi ketika menekan A membuka pemancar RS232, sejak saat itu setiap input akan dikirim melalui RS232. Pada akhirnya proyek ini adalah editor teks yang berdiri sendiri. Jadi, ketika menekan A membuka sistem file, sejak saat itu Anda tidak lagi mengedit teks tetapi melihat melalui daftar file. Itu berarti bahwa menekan Atas dan Bawah berarti sesuatu yang berbeda dari pada lingkungan penyuntingan teks.
Saya telah melakukan banyak pemikiran tentang bagaimana memprogram ini dalam C. Saya memikirkan ini semalam dan ingin tahu apakah itu mungkin dan jika demikian, bagaimana. Yang ingin saya lakukan adalah:
- The
main
fungsi panggilan fungsi sepertifunction_A
function_A
mengubah variabel globalfunction_addr
ke penunjuk alamat fungsiin_function_A
- Sejak saat itu,
main
panggil fungsifunction_addr
ketika ada input baru.
Jadi yang saya butuhkan adalah main
fungsi yang memeriksa apakah function_addr
nol. Jika ya, fungsi 'normal' harus dipanggil, misalnya function_A
. Jika tidak, fungsi di function_addr
harus dipanggil. Saya juga membutuhkan function_A
yang mengubah function_addr
pointer ke in_function_A
.
Catatan: ketika fungsi sistem file harus ditutup, is_function_A
seharusnya berubah function_addr
menjadi 0.
Jadi pada dasarnya pertanyaan saya adalah bagaimana saya bisa
- Dapatkan alamat suatu fungsi (dan simpan dalam variabel)
- Panggil fungsi di alamat yang ditentukan
Jawaban:
Sebuah fungsi
Dapatkan alamat suatu fungsi (dan simpan dalam variabel)
Panggil fungsi di alamat yang ditentukan
sumber
fp(12)
tidak meningkatkan keterbacaan(*fp)(12)
. Mereka memiliki keterbacaan yang berbeda.(*fp)(12)
mengingatkan pembaca yangfp
merupakan penunjuk, dan juga menyerupai deklarasifp
. Dalam pikiran saya, gaya ini dikaitkan dengan sumber-sumber lama, seperti internal X11, dan K&R C. Salah satu alasan yang mungkin dikaitkan dengan K&R C adalah karena dalam ANSI C, dimungkinkan untuk mendeklarasikanfp
menggunakan sintaks fungsi, jikafp
merupakan parameter:int func(int fp(double)) {}
. Dalam K&R C itu seharusnyaint func(fp) int (*fp)(double); { ... }
.Sementara jawaban Wouters benar sekali, ini mungkin lebih ramah bagi pemula dan contoh yang lebih baik tentang pertanyaan Anda.
Jika tidak jelas bahwa pointer fungsi sebenarnya memiliki alamat fungsi target yang ditetapkan, lebih baik untuk melakukan pemeriksaan NULL.
sumber
fp
kebetulan menempati sebenarnya NULL pada awalnya. Saya akan melakukanint (*fp)(int) = NULL;
sebagai deklarasi dan inisialisasi gabungan untuk memastikan - Anda tidak ingin melompat ke beberapa lokasi memori acak karena beberapa nilai konyol yang kebetulan ada di sana. Kemudian, tetapkanfp
seperti padaExample()
fungsi Anda .fp
merupakan "variabel global" (seperti kode int di atas), maka dijamin akan diinisialisasi keNULL
(tanpa harus melakukannya secara eksplisit).