Apakah fungsi void * () berfungsi sebagai penunjuk atau fungsi mengembalikan void *?

26

Saya bingung tentang arti void *function().
Apakah pointer berfungsi atau fungsi kembali void*? Saya selalu menggunakannya pada struktur data sebagai fungsi rekursif mengembalikan pointer, tetapi ketika saya melihat kode di multithreading ( pthread) ada deklarasi fungsi yang sama. Sekarang saya bingung apa bedanya mereka.

pengguna9515151
sumber
5
@goodvibration C dibuat bebas format (dan C ++ "mewarisi" ini). Bahkan void*function();secara sintaksis benar. Misalnya untuk Python mereka memilih format keputusan yang berbeda adalah bagian dari sintaksis. IMHO, kedua cara memiliki pro dan kontra.
Scheff
3
@goodvibration semakin Anda mencoba melindungi programmer dari melakukan apa yang mereka inginkan, semakin Anda mendapatkan sesuatu seperti java;)
idclev 463035818
2
@ goodvibration Opsi kurang, kurang fleksibel. Dan, tolong, ingatlah bahwa sudah puluhan tahun yang lalu ketika mereka melakukannya. Mudah untuk mengeluh sesudahnya ... ;-)
Scheff
2
Dalam bahasa C, void *function()adalah fungsi yang mengambil sejumlah argumen arbitrer dan mengembalikan nilai yang, ketika didereferensi, bertipe batal . Dalam C ++, void* function()adalah fungsi yang tidak mengambil argumen dan mengembalikan nilai pointer-to-void . Anda harus menentukan pilihan bahasa yang Anda tanyakan.
Stephen M. Webb
1
@ StephenM.Webb Anda tidak dapat melakukan dereferensi avoid * . Lagi pula, bahkan jika Anda bisa, apa yang akan Anda lakukan dengan void?
Fabio mengatakan Reinstate Monica

Jawaban:

38

Fungsi memiliki tipe kembali void *.

void *function();

Jadi saya selalu lebih suka dalam kasus seperti itu untuk memisahkan simbol *dari nama fungsi seperti

void * function();

Dan seperti yang Jarod42ditunjukkan dalam komentar Anda dapat menulis ulang deklarasi fungsi dalam C ++ menggunakan tipe trailing return seperti

auto function() -> void *;

Jika Anda ingin mendeklarasikan pointer berfungsi, Anda harus menulis

void ( *function )();

Atau

void * ( *function )();

Atau penunjuk ke fungsi yang mengembalikan penunjuk ke fungsi

void * ( *( *function )() )();
Vlad dari Moskow
sumber
2
Itu sebabnya, saya lebih suka menulis void* function();. Itu tidak menggoda ... ;-) (Pengeditan terjadi tepat saat menulis ini.)
Scheff
dalam kode saya menyatakan void * reader();kemudian pthread_create(&thread1,null,reader,reader_arg)bukanpthread_create(&thread1,null,&reader,reader_arg)
user9515151
1
@Cheff: Atau bahkan auto function() -> void*(C ++). :)
Jarod42
3
Atau pointer berfungsi yang mengembalikan pointer berfungsi Itulah typedefuntuk ... ;-)
Andrew Henle
1
@AndrewHenle Dengan typedef tidak ada masalah. Masalah muncul ketika deklarasi digunakan tanpa typedef atau deklarasi alias. :)
Vlad dari Moscow
7

Setiap kali saya tidak yakin tentang masalah sintaksis C, saya suka menggunakan utilitas cdecl ( versi online ) untuk menerjemahkan bagi saya. Ini menerjemahkan antara sintaks C dan Bahasa Inggris.

Misalnya, saya masukan contoh Anda void *foo()dan dikembalikan

mendeklarasikan foo sebagai fungsi yang mengembalikan pointer ke void

Untuk melihat seperti apa sintaks yang lain, saya masukan declare foo as pointer to function returning voiddan mengembalikannya

batal (* foo) ()

Ini menjadi sangat berguna ketika Anda memiliki beberapa tingkat typecast, bintang, atau tanda kurung dalam satu ekspresi.

bta
sumber
2

Ini adalah fungsi yang mengembalikan pointer ke void.

Pikirkan deklarasi Anda seperti ini:

void *(function());

Ini akan menjadi fungsi yang mengembalikan void(atau tidak sama sekali):

void (*function2)();

Pikirkan pernyataan di atas dengan cara ini:

void ((*function2)());

Cara yang lebih mudah untuk menulis ini adalah dengan menggunakan typedefs:

typedef void *function_returning_void_pointer();
typedef void function_returning_nothing();

function_returning_void_pointer function;
function_returning_nothing *function2;

Ini umumnya menghilangkan kebingungan di sekitar fungsi pointer dan lebih mudah dibaca.

SS Anne
sumber
0

Deklarasi dalam C / C ++ dibaca dari pengidentifikasi ke luar mengikuti prioritas operator .

Pandangan cepat pada tabel prioritas operator C / C ++ di wikipedia mengungkapkan bahwa operator panggilan fungsi ()memiliki prioritas lebih tinggi daripada operator tidak langsung *. Jadi, deklarasi fungsi Anda berbunyi seperti ini:

  • Mulai di pengidentifikasi: functionadalah

  • function() sebuah fungsi yang tidak membutuhkan argumen

  • void* function()dan mengembalikan a void*.

Prinsip umum ini juga berlaku dengan deklarasi array ( []juga memiliki prioritas lebih tinggi dari *) dan kombinasi keduanya. Begitu

int *(*arr[42])();

dibaca sebagai

  • arr adalah
  • arr[42] sebuah array dari 42 elemen yang
  • *arr[42] pointer ke
  • (*arr[42])() fungsi yang tidak mengambil argumen dan
  • int *(*arr[42])()mengembalikan sebuah int*.

Dibutuhkan sedikit untuk membiasakan diri dengan ini, tetapi begitu Anda sudah memahami prinsipnya, mudah untuk membaca deklarasi-deklarasi itu dengan jelas.

cmaster - mengembalikan monica
sumber