Bukankah titik koma (';') diperlukan setelah deklarasi fungsi di C ++?

174

Saya baru saja mengambil tes pemrograman menengah, dan salah satu pertanyaan saya salah adalah sebagai berikut:

Tanda titik koma (';') tidak diperlukan setelah deklarasi fungsi.

Benar atau salah.

Saya memilih "false" (dan tolong perbaiki saya jika saya salah karena saya merasa seperti gila), deklarasi fungsi adalah apa yang Anda tulis sebelum definisi (di bagian atas kode) sehingga kompiler mengetahui fungsi tersebut panggilan bahkan sebelum memanggilnya, dan definisi fungsi adalah apa yang membentuk fungsi secara keseluruhan.

Yaitu,

Pernyataan:

int func();

Definisi:

int func() {
  return 1;
}

Bukankah seharusnya jawabannya salah?

Logan
sumber
41
Definisi juga merupakan deklarasi. Tapi saya akan mengatakan jawaban Anda benar.
216
Ini adalah pertanyaan sulit yang rumit dan tidak mempengaruhi kemampuan siapa pun untuk memprogram dengan baik.
phonetagger
40
Saya selalu menemukan pertanyaan, yang menghasilkan negatif ganda, membingungkan. Dalam benak saya, pertanyaan-pertanyaan seperti itu dirancang untuk membuat siswa tersandung. Mengapa pertanyaan tidak dapat dibentuk dengan cara berikut: "Tanda titik koma (';') selalu diperlukan setelah deklarasi fungsi. Benar atau Salah."? : /
Algirdas Preidžius
18
@ phonetagger Semua kebingungan ini menunjukkan betapa buruknya kata pertanyaannya.
François Andrieux
34
Razor Hanlon menunjukkan bahwa penulis ujian mencampuradukkan "deklarasi" dan "definisi".
Sneftel

Jawaban:

161

Anda dapat memiliki situasi di mana Anda mendeklarasikan dan mendefinisikan fungsi dalam satu langkah, yaitu jika Anda memasukkan definisi fungsi pada titik di mana Anda mendeklarasikannya. Jadi secara teknis saya kira benar itu benar. Tetapi pertanyaan itu diucapkan sedemikian rupa sehingga saya akan menjawabnya seperti yang Anda lakukan.

jwismar
sumber
10
Saya berpendapat bahwa yang benar tidak benar karena alasan yang Anda berikan. Jika ada kasus ketika titik koma diperlukan, maka itu salah (atau tidak benar). Benar adalah mutlak bagi saya, jika ada kasus yang jelas ketika dibutuhkan maka Anda tidak bisa mengatakan benar.
I Funball
16
@ Ifunball Argumen yang bagus. Bahasa natual yang bodoh. Kalimat "Tanda titik koma (';') tidak diperlukan setelah deklarasi fungsi" dapat dibaca sebagai "Tanda titik koma (';') tidak (pernah) diperlukan setelah deklarasi fungsi" atau sebagai "Tanda titik koma (';' ) tidak (selalu) dibutuhkan setelah deklarasi fungsi ". Apakah memenuhi syarat pernyataan sebagai benar atau salah bergantung pada memilih interpretasi. Secara tegas pertanyaannya tidak jelas dan karenanya tidak memiliki jawaban yang jelas.
Peter - Reinstate Monica
6
@ IFunball Itu karena "deklarasi", tanpa konteks lebih lanjut dan tidak ada pernyataan bahwa kita adalah pengacara bahasa, umumnya dipahami sebagai "deklarasi tidak terdefinisi". Pertanyaan itu tidak adil.
Lightness Races di Orbit
2
Semua pertanyaan ujian yang tidak jelas bagi seseorang yang mengetahui konten yang diuji coba disadap.
Nat
2
Kedengarannya seperti kita perlu menambahkan klausa perilaku yang tidak terdefinisi ke bahasa Inggris
Nick Mertin
147

Selain hal "definisi juga pernyataan", berikut ini adalah hukum C ++:

int f(), g();

Ini menyatakan dua fungsi, fdang , keduanya tanpa argumen dan dengan tipe pengembalian int, tetapi definisi ftidak diikuti (segera) oleh tanda titik koma. Demikian juga, ini legal:

int f(), i = 42;

Tetapi memang tidak diperbolehkan untuk menghilangkan titik koma sepenuhnya dalam kasus-kasus ini, sehingga akan agak mengejutkan jika diambil sebagai contoh deklarasi tanpa titik koma berikut. Faktanya, yang berikut ini ilegal:

void *p, f() {}

Selain deklarasi fungsi (hanya), definisi fungsi tidak dapat digabungkan dengan deklarasi atau definisi lain apa pun dengan tipe-specifier yang sama . (Jika ini legal, itu akan menentukan a void *pdan a void f() {}.)

Bagaimanapun, ini tampaknya merupakan jenis pertanyaan "gotcha" yang tidak boleh dalam tes pemrograman tingkat menengah.

(Oh, omong-omong, tolong jangan benar-benar menulis kode seperti int f(), i = 42;.)

Arne Vogel
sumber
2
Dimungkinkan juga untuk menggunakan typedef untuk mendefinisikan tipe fungsi, dan kemudian menggunakannya untuk mendeklarasikan banyak fungsi sekaligus, misalnya typedef int fooProc(int); fooProc a,b.c.d.e;saya tidak yakin mengapa header standar untuk kompiler berbasis floppy-drive tidak melakukan itu kembali di hari, karena saya akan berpikir itu akan memungkinkan file header menjadi jauh lebih kecil dan dengan demikian lebih cepat untuk diproses.
supercat
Juga pertimbangkan int f(int(&g)(),int(*h)()){return g()+h();}Ini memiliki tiga deklarasi fungsi, salah satunya diikuti oleh kurung kurawal terbuka, yang lain dengan koma, dan yang ketiga oleh kurung tutup.
David Hammen
1
@ Davidvidam: Itu tidak secara ketat mendeklarasikan fungsi selain int f(stuff). Bahkan dalam lingkup fungsi, gadalah variabel otomatis tipe referensi ke fungsi , dan hmerupakan pointer ke fungsi .
Peter Cordes
83

Jawaban dan komentar lain menyebut beberapa dari banyak cara bahwa ini adalah pertanyaan yang mengerikan, menyesatkan, dan ditulis dengan buruk. Tetapi ada masalah lain yang belum diidentifikasi orang lain. Pertanyaannya adalah:

Tanda titik koma (';') tidak diperlukan setelah deklarasi fungsi. Benar atau salah.

OK, mari kita lihat deklarasi fungsi:

int func();       /* */
/*           ^       */
/*           |       */
/* That whitespace is "after the function declaration". */

Semuanya adalah deklarasi . Deklarasi tidak int func()dan kemudian diikuti oleh a ;. Deklarasi int func();kemudian diikuti oleh spasi putih.

Jadi, pertanyaannya adalah: apakah titik koma diperlukan setelah deklarasi ? Tentu saja tidak. Deklarasi tersebut sudah memiliki titik koma di dalamnya yang mengakhiri itu. Titik koma setelah deklarasi tidak ada gunanya. Sebaliknya, int func(); ;akan menjadi titik koma setelah deklarasi fungsi .

Pertanyaan itu hampir pasti dimaksudkan untuk mengajukan pertanyaan "benar atau salah: token terakhir dalam deklarasi fungsi selalu merupakan titik koma" Tapi itu bukan pertanyaan yang mereka tulis, karena penulis kuis itu tidak berpikir jernih tentang masalah tersebut.

Saran saya adalah untuk menghindari kuis bahasa pemrograman sama sekali. Mereka sangat mengerikan.


Fakta yang menyenangkan, sementara kita membahasnya. Dalam C #, ini semua legal:

class C {}
class D {};
struct E {}
struct F {};

Dalam C #, deklarasi kelas atau struct dapat diakhiri dengan tanda titik koma, atau tidak, sesuai kebijakan Anda. Fitur kecil yang aneh ini ditambahkan untuk kepentingan pemrogram C / C ++ yang datang ke C # yang memilikinya di ujung jari mereka bahwa deklarasi tipe diakhiri dengan titik koma; tim desain tidak ingin menghukum mereka karena memiliki kebiasaan ini. :-)

Eric Lippert
sumber
Komentar bukan untuk diskusi panjang; percakapan ini telah dipindahkan ke obrolan .
Samuel Liew
25

Anda dapat mendeklarasikan fungsi seperti ini juga:

int func(){
    return 1;
}

Pernyataan itu sangat ambigu. Jawaban yang benar adalah: itu tergantung pada bagaimana Anda mendeklarasikan fungsinya.

Lagi pula, saya akan memilih salah juga, dan mungkin Anda dapat melaporkan pertanyaan itu kepada seseorang.

Luca Corsini
sumber
3
Ngomong-ngomong, jangan letakkan benda itu di level pribadi. Yang penting adalah Anda memahami bagaimana fungsi deklarasi-definisi berfungsi, jadi jangan terlalu khawatir tentang hal itu, pastikan saja pertanyaannya setidaknya akan diperiksa dan dilanjutkan
Luca Corsini
11
Benar. Sejujurnya, saya belajar lebih banyak tentang fungsi deklarasi-definisi dari mendapatkan pertanyaan yang salah daripada yang seharusnya saya dapatkan dengan benar.
Logan
1
@Logan jangan terlalu khawatir. Jika Anda tahu cara menulis dan membaca fungsi itu saja yang Anda butuhkan. Saya pribadi benci pertanyaan-pertanyaan semacam ini yang 1. tidak didefinisikan dengan baik 2. menguji pengetahuan teoretis Anda tentang sintaksis. Bagi saya itu seperti memori otot. Ketika saya menulis setiap digit dengan mudah ke tombol itu seharusnya pergi, tetapi jika Anda memberi saya tes tentang apa yang harus ditekan tombol angka saya akan benar-benar putus asa tanpa keyboard untuk secara fisik melakukan tindakan ...
bolov
2
... Menulis sintaksis umum (mis. Seperti fungsi) akan menjadi kebiasaan Anda. Dan ketika Anda akan mengacaukannya karena Anda baru saja beralih bahasa, well ... intellisense dan highlight sintaks membuat solusi cepat dan efisien. Investasikan waktu dan energi Anda dalam sesuatu yang lebih bermanfaat.
bolov
20

Tanda titik koma (';') tidak diperlukan setelah deklarasi fungsi.

Benar atau salah.

Benar . Titik koma tidak diperlukan setelah deklarasi apa pun. Atau setelah definisi apa pun. Atau setelah pernyataan apa pun.

Banyak jenis deklarasi harus diakhiri dengan titik koma, seperti sintaks pada bagian 7 [dcl.dcl] yang ditentukan. Tetapi tidak perlu menulis yang kedua setelah itu.

Marc van Leeuwen
sumber
1
Saya melihat bahwa Eric Lippert sudah memperdebatkan hal ini. Saya kira semua upvotes membuat saya mengabaikannya. Jangan ragu untuk memberikan suara Anda di sana.
Marc van Leeuwen
Cukup banyak pertanyaan yang bertanya, "X selalu benar: benar atau salah?" akan memiliki jawaban "salah." Heck, tidak perlu memiliki titik koma di mana saja ; kompiler mungkin mengeluh dan menolak untuk mengkompilasi program Anda, tetapi itu bukan akhir dunia; Saya tidak akan menyebutnya kebutuhan mendasar . ;)
Quuxplusone
@Quuxplusone jika kompiler menolak program Anda, program Anda tidak memiliki deklarasi fungsi di dalamnya :)
Ben Millwood
6

Ini tergantung pada apakah kita mendeklarasikan atau mendefinisikan fungsi. Jika kita mendeklarasikan fungsinya, kita perlu menyertakan tanda titik koma (; ), dan jika kita mendefinisikan fungsi, tanda titik koma tidak diperlukan.

Deklarasi seperti ini:

int add(int, int);

Dan definisi adalah seperti ini:

int add(int a, int b)
{
    // ...
}
Rocx En Ruff
sumber
10
Masalah dengan jawaban ini adalah bahwa itu menunjukkan bahwa definisi dan deklarasi saling eksklusif. Faktanya, setiap definisi adalah deklarasi; definisi adalah bagian dari deklarasi.
MSalters
6

Meskipun saya setuju dengan hampir semua jawaban lain, menyatakan bahwa pertanyaannya sangat ambigu, dan bahwa jawaban Anda secara teknis benar, izinkan saya untuk memberikan perspektif yang berbeda:

Beginilah saya selalu memanggil mereka:

void func();  // The function prototype

...

void func()
{
    // The function definition
}

Saya berasumsi pertanyaan itu dibuat dengan terminologi ini dalam pikiran.

Definisi dan deklarasi adalah konsep yang sama di mata saya. "Saya mendefinisikan x = y" == "Saya menyatakan x = y".

Tapi tentu saja, ada perbedaan besar antara prototipe fungsi (di atas) dan definisi fungsi yang sebenarnya.

Opifex
sumber
Bagi saya prototipe Anda adalah deklarasi berdasarkan bagaimana saya belajar (tidak mengatakan Anda salah juga), tapi kemudian saya juga berharap prototipe untuk menentukan jumlah dan jenis argumen, atau batal, tapi saya harap Anda mengabaikannya untuk singkatnya.
David S
David S: Ya, tentu saja itu juga akan berisi jumlah dan jenis argumen, tetapi saya memang menghilangkannya untuk singkatnya (perhatikan bahwa tidak ada argumen dalam deklarasi fungsi sebenarnya). Namun, saya tidak begitu setuju ketika Anda mengatakan deklarasi fungsi penuh disebut prototipe. Saya kutip Wikipedia: "prototipe fungsi atau antarmuka fungsi adalah deklarasi fungsi yang menentukan nama fungsi dan tipe tanda tangan (arity, tipe data parameter, dan tipe kembali), tetapi mengabaikan fungsi tubuh."
Opifex
@ DavidS: Dalam C ++, deklarasi fungsi selalu prototipe (atau definisi), dan void func();persis sama dengan void func(void);. Ini sangat berbeda dari C , di mana void func();tidak memberitahu kompiler apa pun tentang args, dan tidak sama dengan void func(void);. Prototipe atau definisi yang lebih baru adalah ide yang bagus, jika tidak, penelepon harus menerapkan promosi arg default (misalnya float -> double, dan tipe integer sempit untuk int. Aturan yang sama seperti untuk args ke fungsi variadic.)
Peter Cordes
Maaf, saya akhirnya melihat sesuatu yang berhubungan dengan C dan tidak memperhatikan perubahan bahasa. Saya tidak akan menghapus komentar saya untuk kepentingan kejelasan, tetapi menganggapnya ditarik kembali.
David S
6

Sayang sekali pertanyaan yang Anda ambil tidak mengatakan "langsung setelah". Misalnya kita bisa menulis ini:

int func()  /* My function */ ;

Atau saya bisa menulis:

int func()
int a = 42;

Dalam kasus pertama, titik koma tidak secara langsung setelah deklarasi, tetapi itu tidak masalah.

Dalam kasus kedua ada tanda koma "setelah" deklarasi, tetapi tidak secara langsung setelahnya.

Saya pikir Eric Lippert memiliki ide yang tepat dalam jawabannya .

Itu seperti mengatakan "haruskah ada periode setelah akhir kalimat dalam bahasa Inggris?". Bisa dibilang, kalimat sudah memiliki periode di akhir (kalau tidak itu tidak akan menjadi kalimat) dan karenanya tidak boleh ada periode setelah kalimat ..

Nick Gammon
sumber
4
Bagus. Mengakhiri kalimat itu dengan periode tambahan. Saya melihat apa yang Anda lakukan di sana.
David S
2
int func() int a=42;tidak dikompilasi. Anda perlu koma, bukan yang lain int. Lihat jawaban @ Arne yang diposting sehari sebelum ini. Satu-satunya hal baru dalam jawaban ini adalah paragraf terakhir, dengan analogi kalimat bahasa Inggris.
Peter Cordes
1
Saya tidak mengatakan contoh kedua dikompilasi. Saya menunjukkan bahwa mengatakan bahwa titik koma diperlukan "setelah" deklarasi itu ambigu. Contoh saya memiliki titik koma setelah deklarasi tetapi tidak dikompilasi.
Nick Gammon
1
Masalah yang sama terjadi pada pesan kesalahan; contoh favorit dari C # adalah " Parameter params harus menjadi parameter terakhir dalam daftar parameter formal ". Sekarang, anggap saja saya berkata, "Seorang frob harus menjadi gloob terakhir dalam daftar gloob". Apakah ini berarti (1) Setiap daftar gloob memiliki tepat satu frob pada akhirnya, seperti setiap pertanyaan memiliki tepat satu tanda tanya di akhir, (2) Daftar gloob dapat memiliki sejumlah frob, tetapi jika memiliki satu atau lebih frob , item terakhir harus berupa frob, seperti angka genap dapat memiliki nomor 02468, tetapi salah satu harus menjadi yang terakhir, atau ...
Eric Lippert
... (3) daftar gloob dapat memiliki nol atau satu frobs, dan jika ada, itu muncul pada akhirnya? Jika Anda tidak tahu konteksnya, saya akan berpikir bahwa (1) adalah penjelasan yang paling masuk akal, tetapi dalam kasus "parameter params", (3) adalah penjelasan yang benar. Banyak deskripsi informal tentang elemen bahasa pemrograman yang memiliki properti yang oleh teman-teman editor teknis saya sebut "COIK" - Bersihkan Hanya Jika Dikenal. Jika Anda belum memahami materi secara menyeluruh, deskripsi tentang hal itu tidak berguna bagi Anda, tetapi jika Anda sudah memahaminya dengan seksama, Anda tidak perlu deskripsi itu!
Eric Lippert
4

Anda dapat menggunakan ;hanya untuk prototipe.

M7off
sumber
4

Ini semacam pertanyaan rumit, tetapi mereka menggunakan kata deklarasi yang artinya kira-kira seperti ini:

int example();

Jadi benar dalam kasus ini.

Jika mereka menggunakan implementasi kata maka itu salah.

dark_3nergy
sumber
2

Titik koma (;) digunakan untuk memberi tahu kompiler bahwa setelah titik koma (;) ini, sebuah pernyataan baru dimulai.

Jadi saya pikir titik koma (;) diperlukan selama deklarasi fungsi saja. Jadi menurut saya, jawabannya akan benar.

Jatinder
sumber
Deklarasi bukan pernyataan.
HolyBlackCat
tetapi setelah deklarasi fungsi, kami mengeksekusi baris kode baru menggunakan kompiler. jadi saya pikir sebelum mengeksekusi baris baru kompiler kode harus tahu di mana baris kode sebelumnya hanya berakhir maka kompiler dapat menghasilkan kode asli (yaitu 0101).
Jatinder
2

Ketika fungsi didefinisikan sebelum main () :

  • Tidak perlu titik koma karena fungsinya sudah ditentukan

Ketika fungsi didefinisikan setelah main () :

  • Perlu titik koma karena karena Anda membuat prototipe fungsi itu dan memberi tahu kompiler bahwa fungsi keluar.
shiv shah
sumber