Dari jawaban ini di Rekayasa Perangkat Lunak, void
diperlakukan khusus tergantung pada bagaimana itu digunakan. In C
dan C++
, void
digunakan untuk menunjukkan tidak adanya tipe data, sedangkan void *
digunakan untuk menunjukkan pointer yang menunjuk ke beberapa data / ruang dalam memori yang tidak memiliki tipe. void *
tidak dapat disereferensi sendiri, dan harus dilemparkan ke tipe lain terlebih dahulu. Pemeran ini tidak perlu eksplisit dalam C
, tetapi harus eksplisit dalam C++
. (Inilah sebabnya kami tidak memberikan nilai pengembalian malloc, yaitu void *
.)
Ketika digunakan dengan fungsi sebagai parameter, void
berarti tidak adanya parameter apa pun, dan hanya parameter yang diizinkan. Mencoba menggunakan kekosongan seperti tipe variabel atau menyertakan argumen lain menghasilkan kesalahan kompilator:
int foo(void, int); //trying to use "void" as a parameter
int bar(void baz); //trying to use "void" as an argument's type
main.c:1:8: error: 'void' must be the first and only parameter if specified
int foo(void, int);
^
main.c:2:14: error: argument may not have 'void' type
int bar(void baz);
^
Tidak mungkin untuk mendeklarasikan variabel dengan tipe void
:
int main(void) {
void qux; //trying to create a variable with type void
}
main.c:5:8: error: variable has incomplete type 'void'
void qux;
void
sebagai nilai balik untuk fungsi menunjukkan tidak ada data yang akan dikembalikan. Karena tidak mungkin untuk mendeklarasikan variabel tipe void
, tidak mungkin untuk menangkap nilai balik suatu void
fungsi, bahkan dengan pointer kosong.
void foo(int i) { return; }
int main(void) {
void *j;
j = foo(0);
return 0;
}
main.c:5:5: error: assigning to 'void *' from
incompatible type 'void'
j = foo(0);
^ ~~~~~~
Jenis void *
yang berbeda adalah kasus yang berbeda. Pointer batal menunjukkan pointer ke lokasi di memori, tetapi tidak menunjukkan tipe data pada pointer itu. (Ini adalah yang digunakan untuk mencapai polimorfisme dalam C , seperti dengan fungsi qsort () .) Pointer ini bisa rumit untuk digunakan, karena sangat mudah untuk secara tidak sengaja melemparkannya ke tipe yang salah. Kode di bawah ini tidak akan memasukkan kesalahan kompilator C
, tetapi menghasilkan perilaku yang tidak terdefinisi:
#include <stdio.h>
int main(void) {
double foo = 47.2; //create a double
void *bar = &foo; //create a void pointer to that double
char *baz = bar; //create a char pointer from the void pointer, which
//is supposed to hold a double
fprintf(stdout, "%s\n", baz);
}
Namun, kode berikut ini sepenuhnya legal; casting ke dan dari void pointer tidak pernah mengubah nilai yang dimilikinya.
#include <stdio.h>
int main(void) {
double foo = 47.2;
void *bar = &foo;
double *baz = bar;
fprintf(stdout, "%f\n", *baz);
}
47.200000
Sebagai parameter fungsi, void *
menunjukkan bahwa tipe data pada pointer yang Anda lewati tidak diketahui, dan terserah Anda, pemrogram, untuk menangani dengan baik apa pun yang ada di lokasi memori itu. Sebagai nilai balik, void *
menunjukkan bahwa jenis data yang dikembalikan tidak diketahui atau tidak bertipe, dan harus ditangani oleh program.
int quux(void *); //a function that receives a pointer to data whose type is not known, and returns an int.
void *quuz(int); //a function that receives an int, and returns a pointer to data whose type is not known.
tl; dr void
dalam prototipe fungsi berarti "tidak ada data" dan menunjukkan tidak ada nilai balik atau tidak ada parameter, void *
dalam prototipe fungsi berarti "data pada penunjuk fungsi ini diberikan tidak memiliki tipe yang dikenal" dan menunjukkan parameter atau nilai balik penunjuk yang harus dilemparkan ke jenis yang berbeda sebelum data di penunjuk dapat digunakan.