Apa arti batal di C, C ++, dan C #?


170

Mencari untuk mendapatkan dasar-dasar dari mana istilah " void " berasal, dan mengapa itu disebut void. Maksud dari pertanyaan ini adalah untuk membantu seseorang yang tidak memiliki pengalaman C, dan tiba-tiba melihat basis kode berbasis C.


2
Pertanyaan ini mencampur 3 bahasa ... pertanyaan warisan itu harus dibagi menjadi 3 pertanyaan berbeda.
Stargateur

Jawaban:


225

Pada dasarnya itu berarti "tidak ada" atau "tidak ada tipe"

Ada 3 cara dasar yang digunakan untuk membatalkan:

  1. Argumen fungsi: int myFunc(void) - fungsi tidak mengambil apa pun.

  2. Nilai void myFunc(int) pengembalian fungsi : - fungsi tidak mengembalikan apa pun

  3. Penunjuk data umum: void* data - 'data' adalah penunjuk ke data dengan tipe yang tidak dikenal, dan tidak dapat ditinjau ulang

Catatan: voidargumen fungsi dalam adalah opsional di C ++, jadi int myFunc()persis sama dengan int myFunc(void), dan ditinggalkan sepenuhnya dalam C #. Itu selalu diperlukan untuk nilai kembali.


7
batal dalam daftar argumen adalah opsional dalam C ++, lihat stackoverflow.com/questions/416345/…
Daniel Earwicker

1
Saya akan menggunakan "no type" daripada "no size"
Kjetil Joergensen

@Earwicker dan Kjetijor, keduanya adalah poin bagus yang saya perdebatkan, tetapi pikiran saya yang tidak bisa tidur membutuhkan bantuan;) Terima kasih.
Gerald

9
Bukan tidak setuju, tetapi penggunaan tambahan void ada dalam trik "cast to void" untuk menekan peringatan untuk nilai yang tidak digunakan. Agak sulit karena tidak benar-benar sesuai dengan bagaimana kompiler mengartikan sesuatu, tetapi Anda dapat mengartikannya sebagai "Saya menggunakan nilai ini untuk tidak melakukan apa-apa".
Steve Jessop

22
Dalam C ++, void dalam daftar argumen adalah opsional. Namun, dalam C, itu BUKAN opsional: foo () berarti ia mengambil sejumlah parameter dari jenis apa pun, sedangkan foo (void) berarti ia mengambil parameter nol.
Adam Rosenfield

33

Saya selalu menganggapnya absen . Berikut adalah empat kasus dalam bahasa C yang cocok dengan penggunaan absen ini

  • R f(void)- Parameter fungsi tidak ada
  • void f(P)- Nilai pengembalian tidak ada
  • void *p- Jenis yang ditunjuk tidak ada
  • (void) p- Penggunaan nilai tidak ada

Keturunan C lainnya menggunakannya untuk hal lain. Bahasa Dpemrograman menggunakannya untuk kasus-kasus di mana inisialisasi tidak ada

  • T t = void;- nilai inisialisasi tidak ada

4
Apa yang (void)pharus dilakukan Saya tidak mengerti apa yang Anda maksud dengan "penggunaan nilai tidak ada."
Yashas

@Yashas Jika ada yang juga bingung tentang (void) var;pernyataan itu, saya telah menemukan jawaban terinci di stackoverflow.com/q/21045615 .
Arnie97

14

Ada dua cara untuk menggunakan void:

void foo(void);

atau

void *bar(void*);

Yang pertama menunjukkan bahwa tidak ada argumen yang diajukan atau tidak ada argumen yang dikembalikan.

Yang kedua memberitahu kompiler bahwa tidak ada tipe yang terkait dengan data secara efektif yang berarti bahwa Anda tidak dapat menggunakan data yang ditunjukkan sampai itu dilemparkan ke tipe yang dikenal.

Misalnya Anda akan melihat void*banyak digunakan ketika Anda memiliki antarmuka yang memanggil fungsi yang parameternya tidak dapat diketahui sebelumnya.

Sebagai contoh, di Linux Kernel ketika menunda pekerjaan Anda akan mengatur fungsi yang akan dijalankan pada waktu yang terakhir dengan memberikannya sebuah pointer ke fungsi yang akan dijalankan dan sebuah pointer ke data yang akan diteruskan ke fungsi:

struct _deferred_work {
sruct list_head mylist;
.worker_func = bar;
.data        = somedata;
} deferred_work;

Kemudian sebuah thread kernel membahas daftar pekerjaan yang ditangguhkan dan ketika sampai ke node ini, ia secara efektif mengeksekusi:

bar(somedata);

Kemudian di bar Anda memiliki:

void bar(void* mydata) {
    int *data = mydata;
    /* do something with data */;
}

13

Itu berarti "tidak ada nilai". Anda menggunakan voiduntuk menunjukkan bahwa suatu fungsi tidak mengembalikan nilai atau tidak memiliki parameter atau keduanya. Cukup konsisten dengan penggunaan kata void dalam bahasa Inggris.


4

Ini menunjukkan tidak adanya nilai kembali dalam suatu fungsi.

Beberapa bahasa memiliki dua jenis subrutin: prosedur dan fungsi. Prosedur hanyalah urutan operasi, sedangkan fungsi adalah urutan operasi yang mengembalikan hasil.

Dalam C dan turunannya, perbedaan antara keduanya tidak eksplisit. Semuanya pada dasarnya adalah fungsi. yang voidkata kunci menunjukkan bahwa itu bukan fungsi "yang sebenarnya", karena tidak mengembalikan nilai.


3

Pikirkan kekosongan sebagai "struktur kosong". Biarkan saya jelaskan.

Setiap fungsi mengambil urutan parameter, di mana setiap parameter memiliki tipe. Bahkan, kita bisa mengemas parameter ke dalam struktur, dengan slot struktur yang sesuai dengan parameter. Ini membuat setiap fungsi memiliki tepat satu argumen. Demikian pula, fungsi menghasilkan hasil, yang memiliki tipe. Ini bisa berupa boolean, atau bisa jadi float, atau bisa juga struktur, yang berisi sekumpulan nilai-nilai yang diketik secara sewenang-wenang. Jika kita menginginkan languge yang memiliki beberapa nilai balik, mudah untuk bersikeras mereka dikemas ke dalam struktur. Bahkan, kita selalu bisa bersikeras bahwa fungsi mengembalikan struktur. Sekarang setiap fungsi mengambil tepat satu argumen, dan menghasilkan tepat satu nilai.

Sekarang, apa yang terjadi ketika saya membutuhkan fungsi yang menghasilkan nilai "tidak"? Nah, pertimbangkan apa yang saya dapatkan ketika saya membentuk sebuah struct dengan 3 slot: itu memegang 3 nilai. Ketika saya memiliki 2 slot, ia memiliki dua nilai. Ketika memiliki satu slot, satu nilai. Dan ketika memiliki nol slot, ia memegang ... eh, nilai nol, atau "tidak" nilai ".Jadi, saya bisa memikirkan fungsi mengembalikan batal sebagai mengembalikan sebuah struct yang tidak mengandung nilai. Anda bahkan dapat memutuskan bahwa" batal " hanyalah sinonim untuk tipe yang diwakili oleh struktur kosong, bukan kata kunci dalam bahasa (mungkin hanya tipe yang sudah ditentukan sebelumnya :)

Demikian pula, saya dapat memikirkan fungsi yang tidak membutuhkan nilai sebagai menerima struktur kosong, misalnya, "kosong".

Saya bahkan dapat mengimplementasikan bahasa pemrograman saya dengan cara ini. Melewati nilai void membutuhkan nol byte, jadi memberikan nilai void hanyalah kasus khusus untuk melewatkan nilai lain dengan ukuran arbitrer. Ini memudahkan kompiler untuk memperlakukan hasil atau argumen "void". Anda mungkin ingin fitur langauge yang dapat membuang hasil fungsi; di C, jika Anda memanggil fungsi hasil tidak-kosong foo dalam pernyataan berikut: foo (...); kompiler tahu bahwa foo menghasilkan suatu hasil dan mengabaikannya. Jika void adalah nilai, ini berfungsi dengan sempurna dan sekarang "prosedur" (yang hanya kata sifat untuk fungsi dengan hasil batal) hanyalah kasus khusus sepele dari fungsi umum.

Void * sedikit lebih lucu. Saya tidak berpikir perancang C memikirkan kekosongan dengan cara di atas; mereka baru saja membuat kata kunci. Kata kunci itu tersedia ketika seseorang membutuhkan titik ke tipe arbitrer, sehingga membatalkan * sebagai ungkapan dalam C. Itu benar-benar berfungsi dengan baik jika Anda mengartikan kekosongan sebagai struktur kosong. Void * pointer adalah alamat tempat di mana struktur kosong itu diletakkan.

Dipasang dari void * ke T * untuk tipe T lainnya, juga bekerja dengan perspektif ini. Cast pointer adalah cheat lengkap yang bekerja pada arsitektur paling umum untuk mengambil keuntungan dari fakta bahwa jika tipe T senyawa memiliki elemen dengan subtipe S ditempatkan secara fisik pada awal T dalam tata ruang penyimpanannya, kemudian casting S * ke T * dan sebaliknya menggunakan alamat mesin fisik yang sama cenderung berhasil, karena sebagian besar pointer mesin memiliki representasi tunggal. Mengganti tipe S dengan tipe void memberikan efek yang persis sama, dan karenanya casting ke / dari void * berhasil.

Bahasa pemrograman PARLANSE mengimplementasikan ide-ide di atas dengan sangat erat. Kami melakukan kesalahan dalam desainnya, dan tidak memperhatikan "void" sebagai tipe pengembalian dan karenanya memiliki kata kunci langauge untuk prosedur. Sebagian besar itu hanya perubahan sintaksis sederhana tetapi salah satu hal yang tidak bisa Anda lakukan setelah Anda mendapatkan kode besar yang berfungsi dalam suatu bahasa.



2

Tiga kasus penggunaan untuk batal:

  1. Tanda tangan fungsi. void foo(int bar)tidak mengembalikan nilai. int bar(void)tidak mengambil parameter apapun tapi ini biasanya dinyatakan dengan daftar argumen kosong: int bar(). Penggunaan kata kunci batal di sini sesuai dengan artinya dalam bahasa Inggris.

  2. Pointer tipe top generik void *yang menunjuk ke data yang tidak ditentukan dan tidak dapat disereferensi Di sini makna void berbeda dari makna void lainnya: tipe universal vs no type.

  3. Dalam gips seperti (void) new Foo(this)untuk menandakan bahwa nilai pengembalian sengaja dibuang. Di sini, penggunaan kata kunci juga cocok dengan artinya dalam bahasa Inggris.

Kasus 1 dan 2 sudah dicakup oleh @Gerald tetapi kasus 3 belum ditangani.


2

Jika Anda menjelaskan konsepnya kepada seorang pemula, mungkin akan bermanfaat untuk menggunakan analogi. Penggunaan void dalam semua kasus ini analog artinya dengan sebuah halaman dalam buku yang memiliki kata-kata berikut, "Halaman ini sengaja dikosongkan." Ini adalah untuk membedakan ke kompiler antara sesuatu yang harus ditandai sebagai kesalahan, versus jenis yang sengaja dikosongkan karena itu adalah perilaku yang Anda inginkan.

Itu selalu muncul dalam kode di mana biasanya Anda akan mengharapkan untuk melihat jenis muncul, seperti jenis kembali atau jenis penunjuk. Inilah sebabnya mengapa dalam C #, batal memetakan ke tipe CLR yang sebenarnya, System.Void karena itu adalah tipe itu sendiri.

Beberapa bahasa pemrograman tidak pernah mengembangkan konsep void, seperti halnya beberapa budaya manusia tidak pernah menemukan konsep angka nol. Void mewakili kemajuan yang sama dalam bahasa pemrograman seperti konsep nol mewakili bahasa manusia.


Hanya sebuah catatan sehubungan dengan kalimat terakhir Anda - ingatlah bahwa itu hanya berlaku untuk bahasa yang diketik secara statis. Bahasa yang diketik secara dinamis tidak perlu batal karena metode mereka mungkin tidak mengembalikan apa pun - "kekosongan" tersirat oleh kurangnya apa pun yang dikembalikan.
Mark Embling

Koreksi komentar terakhir saya - saya bermaksud mengatakan paragraf terakhir (bukan kalimat).
Mark Embling

1

Itu berarti "tidak ada nilai". Anda menggunakan void untuk menunjukkan bahwa suatu fungsi tidak mengembalikan nilai atau bahwa ia tidak memiliki parameter atau keduanya. Ini lebih konsisten dengan penggunaan khas kata void dalam bahasa Inggris.

Void tidak boleh dikacaukan dengan null. Null berarti untuk variabel yang alamatnya ada di stack, nilai di heap untuk alamat itu kosong.


0

Void hanya digunakan dalam tanda tangan metode. Untuk jenis pengembalian itu berarti metode tidak akan mengembalikan apa pun ke kode panggilan. Untuk parameter artinya, tidak ada parameter yang diteruskan ke metode

misalnya

void MethodThatReturnsAndTakesVoid(void)
{
// Method body
}

Dalam C # kita bisa menghilangkan void untuk parameter dan dapat menulis kode di atas sebagai:

void MethodThatReturnsAndTakesVoid()
{
// Method body
}

Void tidak boleh dikacaukan dengan null. Null berarti untuk variabel yang alamatnya ada di stack, nilai di heap untuk alamat itu kosong.


0

Void adalah tipe tidak lengkap yang, menurut definisi, tidak bisa menjadi nilai. Itu berarti tidak bisa mendapatkan nilai.

Jadi itu juga tidak bisa menyimpan nilai apa pun.


-1

batal artinya Anda tidak akan mengembalikan nilai apa pun dari fungsi atau metode


-1

Void berarti tidak ada nilai yang diperlukan dalam tipe pengembalian dari fungsi dalam ketiga bahasa.


-1

Void adalah setara dengan Sub Visual Basic.


Hanya sebagai tipe pengembalian. Saya dapat memikirkan tiga lagi penggunaan void: void argumen (fungsi tidak mengambil apa-apa), void pointer (tidak ada tipe pointer yang ditentukan), dan void cast (nilai buang).
c4757p
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.