181 lines
5.1 KiB
Markdown
181 lines
5.1 KiB
Markdown
---LESSON_INFO---
|
|
**Learning Objectives:**
|
|
- Memahami konsep pointer fungsi dalam bahasa C
|
|
- Belajar membuat dan menggunakan pointer ke fungsi
|
|
- Mengenal aplikasi pointer fungsi dalam program
|
|
- Memahami bagaimana pointer fungsi digunakan dalam fungsi seperti qsort
|
|
|
|
**Prerequisites:**
|
|
- Pemahaman tentang pointer
|
|
- Pemahaman dasar tentang fungsi
|
|
|
|
---END_LESSON_INFO---
|
|
# Pointer Fungsi dalam C
|
|
|
|
Ingat pointer? Kita menggunakannya untuk menunjuk ke array dari karakter lalu membuat string darinya. Lalu hal-hal menjadi lebih menarik ketika kita belajar cara mengontrol pointer ini. Sekarang saatnya melakukan sesuatu yang bahkan lebih menarik dengan pointer, menggunakan mereka untuk menunjuk ke dan memanggil fungsi.
|
|
|
|
## Mengapa menunjuk ke fungsi?
|
|
Pertanyaan pertama yang mungkin muncul di benak Anda adalah mengapa kita menggunakan pointer untuk memanggil fungsi ketika kita bisa langsung memanggil fungsi dengan namanya: `function();` - itu pertanyaan yang bagus!
|
|
Sekarang bayangkan fungsi `sort` di mana Anda perlu mengurutkan array. Terkadang Anda ingin mengurutkan elemen array dalam urutan menaik atau menurun. Bagaimana Anda memilih? Pointer fungsi!
|
|
|
|
## Sintaks Pointer Fungsi
|
|
```c
|
|
void (*pf)(int);
|
|
```
|
|
|
|
Saya setuju dengan Anda. Ini memang sangat rumit, atau begitulah yang mungkin Anda pikirkan. Mari kita baca ulang kode itu dan coba pahami secara perlahan. Baca dari dalam ke luar.
|
|
`*pf` adalah pointer ke fungsi. `void` adalah tipe kembalian dari fungsi itu, dan akhirnya `int` adalah tipe argumen dari fungsi itu. Mengerti? Baik.
|
|
Mari kita masukkan pointer ke dalam pointer fungsi dan coba baca lagi:
|
|
```c
|
|
char* (*pf)(int*)
|
|
```
|
|
|
|
Lagi:
|
|
1. `*pf` adalah pointer fungsi.
|
|
2. `char*` adalah tipe kembalian dari fungsi itu.
|
|
3. `int*` adalah tipe dari argumen.
|
|
|
|
Oke cukup teori. Mari kita coba dengan kode nyata. Lihat contoh ini:
|
|
|
|
```c
|
|
#include <stdio.h>
|
|
void someFunction(int arg)
|
|
{
|
|
printf("This is someFunction being called and arg is: %d\\n", arg);
|
|
printf("Whoops leaving the function now!\\n");
|
|
}
|
|
|
|
main()
|
|
{
|
|
void (*pf)(int);
|
|
pf = &someFunction;
|
|
printf("We're about to call someFunction() using a pointer!\\n");
|
|
(pf)(5);
|
|
printf("Wow that was cool. Back to main now!\\n\\n");
|
|
}
|
|
```
|
|
|
|
Ingat `sort()` yang kita bicarakan sebelumnya? Kita bisa melakukan hal yang sama dengan itu. Alih-alih mengurutkan set dalam urutan menaik kita bisa melakukan kebalikannya menggunakan fungsi perbandingan kita sendiri sebagai berikut:
|
|
|
|
```c
|
|
#include <stdio.h>
|
|
#include <stdlib.h> //for qsort()
|
|
int compare(const void* left, const void* right)
|
|
{
|
|
return (*(int*)right - *(int*)left); // kembali ke referensi jika ini tampak rumit: http://www.cplusplus.com/reference/cstdlib/qsort/
|
|
}
|
|
|
|
main()
|
|
{
|
|
int (*cmp) (const void* , const void*);
|
|
cmp = &compare;
|
|
int iarray[] = {1,2,3,4,5,6,7,8,9};
|
|
qsort(iarray, sizeof(iarray)/sizeof(*iarray), sizeof(*iarray), cmp);
|
|
int c = 0;
|
|
while (c < sizeof(iarray)/sizeof(*iarray))
|
|
{
|
|
printf("%d \\t", iarray[c]);
|
|
c++;
|
|
}
|
|
}
|
|
```
|
|
|
|
Mari kita ingat lagi. Mengapa kita menggunakan pointer fungsi?
|
|
1. Untuk memungkinkan programmer menggunakan pustaka untuk penggunaan yang berbeda -> "Fleksibilitas"
|
|
|
|
---
|
|
|
|
## Tabel Sintaks Pointer Fungsi
|
|
|
|
| Sintaks | Deskripsi | Contoh |
|
|
|---------|-----------|--------|
|
|
| `void (*pf)(int)` | Pointer ke fungsi yang menerima int dan mengembalikan void | `void (*pf)(int)` |
|
|
| `pf = &function` | Menetapkan alamat fungsi ke pointer | `pf = &myFunction` |
|
|
| `(*pf)(args)` | Memanggil fungsi melalui pointer | `(*pf)(5)` |
|
|
| `pf(args)` | Memanggil fungsi melalui pointer (cara lain) | `pf(5)` |
|
|
|
|
---EXERCISE---
|
|
|
|
# Latihan: Array dari Pointer Fungsi
|
|
|
|
Lengkapi array dari pointer ke fungsi dan panggil setiap fungsi menggunakan pointer dari array. Array dari pointer ke fungsi? Ya Anda bisa melakukan itu!
|
|
|
|
**Requirements:**
|
|
- Buat array dari pointer fungsi
|
|
- Gunakan array untuk memanggil fungsi-fungsi
|
|
- Pastikan setiap fungsi dipanggil dengan indeks sebagai argumen
|
|
|
|
**Expected Output:**
|
|
```
|
|
this is f1 and var is: 0
|
|
this is f2 and var is: 1
|
|
this is f3 and var is: 2
|
|
```
|
|
|
|
Try writing your solution in the code editor below!
|
|
|
|
---EXPECTED_OUTPUT---
|
|
this is f1 and var is: 0
|
|
this is f2 and var is: 1
|
|
this is f3 and var is: 2
|
|
---END_EXPECTED_OUTPUT---
|
|
|
|
---INITIAL_CODE---
|
|
#include <stdio.h>
|
|
void f1(int var)
|
|
{
|
|
printf("this is f1 and var is: %d\\n", var);
|
|
}
|
|
|
|
void f2(int var)
|
|
{
|
|
printf("this is f2 and var is: %d\\n", var);
|
|
}
|
|
|
|
void f3(int var)
|
|
{
|
|
printf("this is f3 and var is: %d\\n", var);
|
|
}
|
|
|
|
int main()
|
|
{
|
|
/* define an array full of function pointers to the above functions, that take an `int` as their only argument */
|
|
int c = 0;
|
|
while(c < 3)
|
|
{
|
|
/* call the functions using the function pointers of the array at index `c` with `c` as an argument */
|
|
++c;
|
|
}
|
|
return 0;
|
|
}
|
|
---END_INITIAL_CODE---
|
|
|
|
---SOLUTION_CODE---
|
|
#include <stdio.h>
|
|
void f1(int var)
|
|
{
|
|
printf("this is f1 and var is: %d\\n", var);
|
|
}
|
|
|
|
void f2(int var)
|
|
{
|
|
printf("this is f2 and var is: %d\\n", var);
|
|
}
|
|
|
|
void f3(int var)
|
|
{
|
|
printf("this is f3 and var is: %d\\n", var);
|
|
}
|
|
|
|
int main()
|
|
{
|
|
void (*pf[])(int) = {f1, f2, f3};
|
|
int c = 0;
|
|
while(c < 3)
|
|
{
|
|
pf[c](c);
|
|
++c;
|
|
}
|
|
return 0;
|
|
}
|
|
---END_SOLUTION_CODE--- |