Apakah mungkin untuk melakukan dereferensi pointer kosong tanpa tipe-casting dalam bahasa pemrograman C?
Juga, adakah cara menggeneralisasi suatu fungsi yang dapat menerima pointer dan menyimpannya dalam pointer kosong dan dengan menggunakan pointer kosong itu, dapatkah kita membuat fungsi umum?
untuk misalnya:
void abc(void *a, int b)
{
if(b==1)
printf("%d",*(int*)a); // If integer pointer is received
else if(b==2)
printf("%c",*(char*)a); // If character pointer is received
else if(b==3)
printf("%f",*(float*)a); // If float pointer is received
}
Saya ingin membuat fungsi ini generik tanpa menggunakan pernyataan if-else - apakah ini mungkin?
Juga jika ada artikel internet yang bagus yang menjelaskan konsep void pointer, maka akan bermanfaat jika Anda bisa memberikan URL.
Juga, apakah pointer aritmatika dengan pointer kosong mungkin?
sumber
void *
pointer sama sepertichar *
, tapi itu bukan standar dan Anda tidak boleh bergantung padanya.Dalam C, a
void *
dapat dikonversi menjadi pointer ke objek dari tipe yang berbeda tanpa gips eksplisit:Ini tidak membantu menulis fungsi Anda dengan cara yang lebih umum.
Anda tidak dapat melakukan dereferensi
void *
dengan mengonversinya ke jenis pointer yang berbeda karena dereferencing pointer memperoleh nilai objek yang ditunjuk. Telanjangvoid
bukan jenis yang valid sehingga derefencing avoid *
tidak mungkin.Aritmetika pointer adalah tentang mengubah nilai pointer dengan kelipatan objek
sizeof
yang ditunjuk-ke. Sekali lagi, karenavoid
bukan tipe yang benar,sizeof(void)
tidak memiliki makna sehingga aritmatika pointer tidak validvoid *
. (Beberapa implementasi memungkinkan, menggunakan aritmatika pointer setara untukchar *
.)sumber
void abc(void *a, int b)
. Tapi mengapa tidak digunakanvoid abc(int *a, int b)
, karena pada fungsi Anda, Anda akhirnya akan mendefinisikanint *test = a;
, itu akan menyimpan satu variabel, dan saya tidak melihat kelebihan lainnya dengan mendefinisikan variabel lain. Saya melihat banyak kode yang ditulis dengan cara ini menggunakanvoid *
sebagai parameter, dan casting variabel nanti dalam fungsinya. Tetapi karena fungsi ini ditulis oleh penulis, maka ia harus tahu penggunaan variabel, oleh karena itu, mengapa menggunakanvoid *
? Terima kasihAnda harus menyadari bahwa di C, tidak seperti Java atau C #, sama sekali tidak ada kemungkinan untuk berhasil "menebak" jenis objek yang
void*
ditunjuk oleh pointer. Sesuatu yang mirip dengangetClass()
tidak ada, karena informasi ini tidak dapat ditemukan. Untuk alasan itu, jenis "generik" yang Anda cari selalu datang dengan metainformation eksplisit, sepertiint b
pada contoh Anda atau string format dalamprintf
keluarga fungsi.sumber
Pointer void dikenal sebagai pointer generik, yang dapat merujuk ke variabel tipe data apa pun.
sumber
Sejauh ini pernyataan saya tentang void pointer adalah sebagai berikut.
Ketika variabel pointer dinyatakan menggunakan kata kunci void - itu menjadi variabel pointer tujuan umum. Alamat variabel apa pun dari tipe data apa pun (char, int, float dll.) Dapat ditetapkan ke variabel penunjuk kosong.
Karena pointer tipe data lain dapat ditugaskan ke void pointer, jadi saya menggunakannya dalam fungsi absolut_value (kode yang ditunjukkan di bawah). Untuk membuat fungsi umum.
Saya mencoba untuk menulis kode C sederhana yang mengambil integer atau float sebagai argumen dan mencoba membuatnya + ve, jika negatif. Saya menulis kode berikut,
Tapi saya mendapatkan kesalahan, jadi saya tahu bahwa pemahaman saya dengan void pointer tidak benar :(. Jadi sekarang saya akan bergerak ke arah untuk mengumpulkan poin mengapa begitu.
Hal-hal yang perlu saya pahami lebih lanjut tentang void pointer adalah itu.
Kita perlu mengetikkan variabel void pointer untuk melakukan dereferensi. Ini karena void pointer tidak memiliki tipe data yang terkait dengannya. Tidak ada cara kompiler dapat mengetahui (atau menebak?) Tipe data apa yang ditunjuk oleh void pointer. Jadi untuk mengambil data yang ditunjuk oleh void pointer kita mengetikkannya dengan tipe data yang benar yang disimpan di dalam lokasi void pointer.
Void pointer bisa sangat berguna jika programmer tidak yakin tentang tipe data dari data yang dimasukkan oleh pengguna akhir. Dalam kasus seperti itu, programmer dapat menggunakan void pointer untuk menunjuk ke lokasi tipe data yang tidak dikenal. Program ini dapat diatur sedemikian rupa untuk meminta pengguna untuk menginformasikan tipe data dan tipe casting dapat dilakukan sesuai dengan informasi yang dimasukkan oleh pengguna. Cuplikan kode diberikan di bawah ini.
Poin penting lain yang harus Anda ingat tentang void pointer adalah bahwa - pointer aritmatika tidak dapat dilakukan dalam void pointer.
Jadi sekarang saya mengerti apa kesalahan saya. Saya mengoreksi hal yang sama.
Referensi :
http://www.antoarts.com/void-pointers-in-c/
http://www.circuitstoday.com/void-pointers-in-c .
Kode baru seperti yang ditunjukkan di bawah ini.
Terima kasih,
sumber
Tidak, itu tidak mungkin. Jenis apa yang harus dimiliki nilai dereferensi?
sumber
sumber
printf
. Jawaban ini memiliki contoh yang bagus untuk itu.int b
dengan enum, tetapi membuat perubahan kemudian pada enum itu akan merusak fungsi ini.Satu-satunya cara sederhana yang saya lihat adalah menggunakan overloading .. yang tidak tersedia dalam bahasa pemrograman C AFAIK.
Apakah Anda mempertimbangkan bahasa pemrograman C ++ untuk program Anda? Atau adakah kendala yang melarang penggunaannya?
sumber
Berikut ini adalah pointer singkat tentang
void
pointer: https://www.learncpp.com/cpp-tutorial/613-void-pointers/Dengan asumsi memori mesin adalah byte-addressable dan tidak memerlukan akses yang selaras, cara paling umum dan atomik (paling dekat dengan representasi level mesin) menafsirkan
void*
adalah sebagai pointer-ke-byteuint8_t*
,. Casting avoid*
ke auint8_t*
akan memungkinkan Anda untuk, misalnya, mencetak byte pertama 1/2/4/8 / namun-banyak-Anda-keinginan mulai dari alamat itu, tetapi Anda tidak bisa melakukan banyak hal lain.sumber
Anda dapat dengan mudah mencetak printer batal
sumber
void
memiliki ukuran yang samaint
?void
pointer, itu mencetakint
pada alamat memori yang berisi pointer (yang dalam hal ini akan menjadi nilaip
).Karena C adalah bahasa yang diketik secara statis, diketik dengan sangat kuat, Anda harus memutuskan jenis variabel sebelum dikompilasi. Saat Anda mencoba meniru obat generik dalam C, Anda akan berakhir mencoba menulis ulang C ++ lagi, jadi lebih baik menggunakan C ++.
sumber
void pointer adalah pointer umum .. Alamat dari semua tipe data dari variabel apa pun dapat ditugaskan ke sebuah void pointer.
sumber
Anda tidak dapat melakukan dereferensi pointer tanpa menentukan jenisnya karena tipe data yang berbeda akan memiliki ukuran yang berbeda dalam memori yaitu int menjadi 4 byte, karakter menjadi 1 byte.
sumber
Pada dasarnya, dalam C, "jenis" adalah cara untuk menafsirkan byte dalam memori. Misalnya, apa kode berikut ini
Mengatakan "Ketika saya menjalankan main, saya ingin mengalokasikan 4 (ukuran integer) + 4 (ukuran integer) = 8 (total byte) memori. Ketika saya menulis '.x' sebagai nilai pada nilai dengan label tipe Arahkan pada waktu kompilasi, ambil data dari lokasi memori pointer plus empat byte. Berikan nilai kembali label waktu kompilasi "int." "
Di dalam komputer saat runtime, struktur "Point" Anda terlihat seperti ini:
Dan inilah yang
void*
tampak seperti tipe data Anda : (dengan asumsi komputer 32-bit)sumber
Ini tidak akan berfungsi, namun void * dapat banyak membantu dalam mendefinisikan pointer umum ke fungsi dan meneruskannya sebagai argumen ke fungsi lain (mirip dengan panggilan balik di Jawa) atau mendefinisikannya struktur yang mirip dengan oop.
sumber