Pertukaran Generik
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan C di Coddy. Pelajaran 51 dari 61.
Salah satu operasi umum dalam pemrograman adalah menukar dua nilai. Biasanya, kamu akan menulis fungsi swap terpisah untuk setiap tipe: satu untuk int, satu lagi untuk double, dan seterusnya. Namun, dengan void* dan memcpy, kita bisa menulis satu fungsi yang menukar dua variabel apa pun.
Inti utamanya adalah bahwa pertukaran hanya memindahkan byte. Jika kamu mengetahui ukuran data, kamu dapat menyalin byte tanpa mengetahui tipe sebenarnya. Deklarasi fungsi terlihat seperti ini:
void generic_swap(void* a, void* b, size_t size);Parameter size memberi tahu fungsi berapa banyak byte yang harus dipindahkan. Di dalamnya, kita menggunakan buffer sementara dan memcpy dari <string.h> untuk menukar byte:
void generic_swap(void* a, void* b, size_t size) {
char temp[size]; // buffer sementara
memcpy(temp, a, size); // temp = a
memcpy(a, b, size); // a = b
memcpy(b, temp, size); // b = temp
}Sekarang fungsi tunggal ini berfungsi untuk tipe apa pun:
int x = 5, y = 10;
generic_swap(&x, &y, sizeof(int));
// x sekarang bernilai 10, y sekarang bernilai 5double p = 3.14, q = 2.71;
generic_swap(&p, &q, sizeof(double));
// p sekarang bernilai 2.71, q sekarang bernilai 3.14Pola ini, yang menggunakan void* dengan size_t, adalah cara pustaka standar C mengimplementasikan fungsi generik seperti qsort dan bsearch.
Tantangan
MudahMari kita buat utilitas swap generik yang dapat menukar nilai dua variabel apa pun, apa pun tipenya, dengan memanfaatkan pointer void* dan memcpy.
Kamu akan menyusun kodemu dalam tiga file:
swap.h: Deklarasikan fungsigeneric_swapyang menerima dua pointervoid*dan parametersize_tyang menunjukkan ukuran data yang akan ditukar. Jangan lupa menambahkan include guard!swap.c: Implementasikan fungsigeneric_swap. Gunakan buffer sementara danmemcpyuntuk memindahkan byte di antara dua lokasi memori. Ingat pola swap tiga langkah: salin nilai pertama ke temp, salin nilai kedua ke nilai pertama, lalu salin temp ke nilai kedua.main.c: Tunjukkan cara kerja swap generik dengan berbagai tipe data. Baca penanda tipe (iuntuk bilangan bulat,duntuk bilangan double), lalu baca dua nilai. Buat dua variabel dengan tipe yang sesuai, tukar nilainya menggunakan fungsigeneric_swap, lalu cetak kedua nilai setelah ditukar.
Programmu akan menerima tiga input:
- Penanda tipe:
iuntuk bilangan bulat atauduntuk double - Nilai pertama
- Nilai kedua
Setelah menukar nilainya, cetak kedua nilai pada baris terpisah. Untuk double, gunakan 2 angka di belakang koma.
Contoh output saat inputnya adalah i, 5, dan 10:
10
5Contoh output saat inputnya adalah d, 3.14, dan 2.71:
2.71
3.14Contoh output saat inputnya adalah i, -7, dan 42:
42
-7Contoh output saat inputnya adalah d, 99.99, dan 0.01:
0.01
99.99Keunggulan pendekatan ini adalah fungsi generic_swap tidak perlu mengetahui tipe apa yang sedang ditukarnya. Fungsi itu hanya memindahkan byte. Fungsi yang sama dapat digunakan untuk bilangan bulat, double, struct, atau tipe data lainnya. Kamu perlu menyertakan <string.h> untuk memcpy dan <stddef.h> atau <stdlib.h> untuk size_t.
Coba sendiri
#include <stdio.h>
#include "swap.h"
int main() {
char type;
scanf("%c", &type);
if (type == 'i') {
int a, b;
scanf("%d", &a);
scanf("%d", &b);
// TODO: Panggil generic_swap untuk menukar a dan b
// Petunjuk: Gunakan &a, &b, dan sizeof(int)
printf("%d\n", a);
printf("%d\n", b);
} else if (type == 'd') {
double a, b;
scanf("%lf", &a);
scanf("%lf", &b);
// TODO: Panggil generic_swap untuk menukar a dan b
// Petunjuk: Gunakan &a, &b, dan sizeof(double)
printf("%.2f\n", a);
printf("%.2f\n", b);
}
return 0;
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Objek
1Dasar-Dasar Pemrograman Modular
file headerProteksi includefile sumberFungsi StatisRingkasan: Kalkulator Modular4Enkapsulasi
Konsep Opaque PointerMendefinisikan Opaque StructGetter dan SetterValidasi pada SetterUlasan: Kotak Rahasia7Pointer Fungsi
Mendeklarasikan Pointer FungsiMemanggil Pointer FungsiTypedef untuk Pointer FungsiMengirim Fungsi sebagai ArgumenRangkuman: Dispatch Kalkulator10Wadah Generik
Tinjauan Ulang Pointer VoidPembungkus GenerikPertukaran GenerikPerbandingan GenerikTinjauan Ulang: Generic array2Object dan method
Struct sebagai objectPointer 'self'Konsistensi constPointer vs nilaiMethod pembantuRangkuman: Pengelola Point5Proyek: Akun Bank Sederhana
Penyiapan ProyekImplementasi Akun3Siklus Hidup object
Pola KonstruktorPola DestruktorInisialisasi StackSalinan MendalamRangkuman: Pembungkus string6Pewarisan melalui Komposisi
Penyematan StructAturan Anggota PertamaMengakses Anggota ParentUpcastingRekap: Hierarki Bentuk9Proyek: Penggambar Bentuk
Ringkasan ProyekImplementasi LingkaranImplementasi Persegi PanjangPenggunaan PolimorfismeWadah BentukLatihan sendiri: Compiler C online