Pertanyaan Mengapa satu fungsi liner membutuhkan kawat gigi?


Kami bisa melakukan ini

if(condition)
    doThis();

dan ini

while(condition)
    doThat();

tapi bukan ini

int giveMeFive()
    return 5; // Error: expected a '{'

Kenapa tidak?

Saya sadar bahwa tata bahasa membutuhkan { dan } pada definisi fungsi. Saya bertanya tentang alasan untuk perbedaan antara pernyataan kondisional (yang tidak memerlukan tanda kurung) dan definisi fungsi (yang dilakukan).


5
2017-08-05 17:14


asal


Jawaban:


Alasannya tampaknya sebagian besar sejarah.

Sebelum tahun 1989 ANSI C standar, C tidak memiliki prototipe. Parameter jenis int dapat didefinisikan secara implisit; parameter jenis selain int harus didefinisikan secara eksplisit, sebelum pembukaan {.

Misalnya, di mana di C modern kita bisa menulis:

double sum(double x, double y) {
    return x + y;
}

di pra-ANSI (K & R) C kami harus menulis:

double sum(x, y)
double x;
double y;
{
    return x + y;
}

Tubuh fungsi mungkin dimulai dengan pernyataan variabel lokal:

double sum(x, y)
double x;
double y;
{
    double z;
    /* ... */
}

Pembukaan { diperlukan untuk memisahkan definisi parameter dari tubuh fungsi, dan penutupan } diperlukan untuk mencocokkan pembukaan {.

(Sintaks ini masih diperbolehkan, tetapi usang, dalam C modern; tidak diizinkan di C ++.)

Ketika prototipe ditambahkan ke bahasa, tidak ada alasan khusus untuk mengizinkan penghapusan { dan } dalam definisi fungsi.

Jawaban sepele adalah bahwa itulah yang dibutuhkan oleh tata bahasa. Sintaks untuk a definisi fungsi aku s:

deklarator-deklarator deklarator deklarasi-daftarmemilih pernyataan majemuk

dimana pernyataan majemuk terdiri dari {, diikuti oleh 0 atau lebih deklarasi dan pernyataan, diikuti oleh }. Ini adalah hanya produksi sintaks yang membutuhkan pernyataan majemuk; ada banyak orang lain yang hanya membutuhkan pernyataan.

Menariknya, dalam bahasa pendahulunya C, disebut B (didokumentasikan di sini), sintaks dari definisi fungsi adalah:

name ( arguments ) statement

Pernyataan itu biasanya pernyataan majemuk (blok yang dibatasi oleh { dan }), tetapi tidak diperlukan. B tidak memerlukan, atau bahkan memperbolehkan, argumen dan variabel memiliki jenis yang ditentukan, jadi tidak perlu memiliki sintaks khusus untuk memisahkan daftar argumen yang disisipkan dari tubuh fungsi. Dalam referensi C paling awal saya dapat menemukan (yang ini, dari tahun 1974), sintaks dari definisi fungsi telah diubah untuk membutuhkan pernyataan majemuk, mungkin untuk mengakomodasi penambahan deklarasi parameter.


12
2017-08-05 17:28



Jika diizinkan, tidak akan ada perbedaan antara deklarasi fungsi:

void a();

dan definisi fungsi untuk fungsi yang tidak melakukan apa-apa:

void a()
  ;

Itu akan menambah lebih banyak masalah daripada mendapatkan pasti.


10
2017-08-05 17:25



Saya pikir masalahnya adalah sulit membedakan konstruksi ini

int giveMeFive()
return 5;

dan konstruksi ini

int giveMeFive() //;
                 ^^^
return 5;

Yaitu apakah programmer itu salah ketik.

Saat ini kompilator mengeluarkan kesalahan. Tetapi apa yang harus dilakukan jika definisi fungsi seperti itu akan diizinkan? Ini akan membuat programnya kurang jelas.

Bahkan bisa digunakan seperti fungsi inline yang disederhanakan

T function( parameter-list ) return expression;

Namun menempatkan titik koma antara header fungsi dan tubuhnya

T function( parameter-list ) ; return expression;

mengubah simpati dan membuat kode tidak jelas.

Perbedaannya misalnya dengan pernyataan sementara adalah bahwa titik koma setelah pernyataan sementara seperti ini

while( condition );

tidak mengubah definisi konstruksi. Dalam hal apapun itu adalah pernyataan sementara.

Namun relatif terhadap definisi fungsi situasinya berbeda.


-2
2017-08-05 17:17