Dalam banyak bahasa (daftar yang luas, dari C ke JavaScript):
- koma
,
argumen terpisah (mis.func(a, b, c)
), sementara - titik koma
;
memisahkan instruksi berurutan (misalnyainstruction1; instruction2; instruction3
).
Jadi mengapa pemetaan ini dibalik dalam bahasa yang sama untuk loop :
for ( init1, init2; condition; inc1, inc2 )
{
instruction1;
instruction2;
}
alih-alih (yang tampaknya lebih alami bagi saya)
for ( init1; init2, condition, inc1; inc2 )
{
instruction1;
instruction2;
}
?
Tentu, for
adalah (biasanya) bukan fungsi, tetapi argumen (yaitu init
, condition
, increment
) berperilaku lebih seperti argumen dari fungsi dari urutan instruksi.
Apakah karena alasan historis / konvensi, atau adakah alasan yang bagus untuk pertukaran ,
dan ;
dalam perulangan?
programming-languages
syntax
loops
Piotr Migdal
sumber
sumber
;
tidak menggunakan|
?" (atau Mengapa kita menggunakan 'lain' bukan 'sebaliknya'? )) yang tidak berlaku untuk satu bahasa, tetapi sejumlah besar dari mereka. Sebuah jawaban yang misalnya "itu dibuat dalam C sebagai singkatan untuk sementara loop (dan beberapa pernyataan untuk inc baru dipikirkan kemudian), dan orang-orang tidak ingin mengubahnya untuk menghindari iritasi programmer" akan baik-baik saja.Jawaban:
Secara teknis, pemetaan tidak "terbalik".
Pada kenyataannya apa yang kita miliki di sini adalah konteks sintaksis yang berbeda di mana simbol yang sama digunakan secara berbeda. Kami tidak membandingkan suka dengan suka, jadi tidak ada pemetaan, dan tidak ada argumen kuat untuk pemetaan konsisten berdasarkan konsistensi semantik.
Jadi mengapa tidak melakukannya sebaliknya?
Yah saya pikir alasannya datang dari makna "alami" dari
,
dan;
. Dalam bahasa tertulis Inggris, tanda titik koma adalah "lebih kuat" istirahat daripada koma, dan mesin terbang untuk tanda koma lebih terlihat daripada koma. Dua hal itu bergabung untuk membuat pengaturan yang sekarang tampak (bagi saya!) Menjadi lebih alami.Tetapi satu-satunya cara untuk mengetahui dengan pasti mengapa pilihan sintaks dibuat adalah jika desainer C dapat memberi tahu kami apa yang mereka pikirkan pada ~ 1970. Saya ragu mereka memiliki ingatan yang jelas tentang keputusan teknis yang dibuat sejauh itu.
Saya tidak mengetahui bahasa apa pun sebelum C yang menggunakan sintaks mirip C untuk loop "for":
Donal Fellows mencatat bahwa BCPL dan B tidak memiliki konstruksi yang setara.
Setara FORTRAN, COBOL dan Algol-60 (dan Pascal) kurang ekspresif, dan memiliki sintaksis yang tidak menyerupai sintaks C "untuk".
Tetapi bahasa seperti C, C ++ dan Java yang muncul setelah C semuanya dengan jelas meminjam sintaks "untuk" dari C.
sumber
,
vs;
) adalah (break lebih lemah vs kuat), bukan (tuple- vs sequence-splitter), kan? Masih bagi saya tidak jelas apakah argumen atau pernyataan membutuhkan jeda yang lebih kuat (seperti dalam banyak kasus untuk urutan pernyataan, jeda adalah implisit (lihat misalnya JavaScript (misalnyai++[line break]j++
))), tetapi setidaknya sekarang saya mendapatkan poin mengapa konvensi saat ini tidak "jelas terbalik".FOR i = e1 TO e2 BY e3 DO c
(ekspresi e1..e3, perintah c), yang lebih mirip dengan sintaksis BASIC. Sumberfor
sintaks diperkenalkan di C (bukan di B atau BCPL).Kami menulis loop seperti:
Bahasanya bisa didefinisikan sehingga loop tampak seperti:
Namun, pikirkan loop yang sama diimplementasikan menggunakan loop sementara:
Perhatikan bahwa pernyataan
x=0
danx++
adalah, diakhiri dengan titik koma. Mereka bukan ekspresi seperti yang akan Anda miliki dalam panggilan fungsi. Titik koma digunakan untuk memisahkan pernyataan, dan karena dua dari tiga elemen dalam for for adalah pernyataan, itulah yang digunakan di sana. A for loop hanyalah jalan pintas untuk loop sementara.Selain itu, argumen tidak benar-benar bertindak seperti argumen untuk suatu fungsi. Yang kedua dan ketiga dievaluasi berulang kali. Memang benar mereka tidak berurutan, tetapi mereka juga bukan argumen fungsi.
Juga, fakta bahwa Anda dapat menggunakan koma untuk memiliki banyak pernyataan dalam for for sebenarnya adalah sesuatu yang bisa Anda lakukan di luar for for.
adalah pernyataan yang benar-benar valid bahkan di luar for for loop. Saya tidak tahu adanya penggunaan praktis di luar for loop. Tetapi intinya adalah bahwa koma selalu membagi pernyataan; ini bukan fitur khusus dari for loop.
sumber
x = 0; y = 0;
dan (di dalam kurung keriting)x++; y++;
...;
adalah alami untuk urutan pernyataan , tidak harus memisahkan pernyataan apa pun (jadi apakah hanya rasanya berbeda?). Dan dalam konvensi saat ini, seseorang kadang-kadang berakhir dengan memisahkan urutan pernyataan dengan koma ...(foo)?bar++, qux++:bletch
--- Di mana Anda ingin?:
ekspresi melakukan dua hal, bukan hanya satu. Nilai kembali jikafoo
itu benarqux
, tetapi keduanyabar
danqux
bertambah.Dalam C dan C ++ ini adalah operator koma, bukan hanya koma.
Tata bahasanya
for
adalah sepertiDalam hal pertanyaan Anda:
Perhatikan bahwa operator-koma memungkinkan Anda untuk melakukan beberapa tindakan dalam satu pernyataan (seperti yang dilihat kompilator). Jika saran Anda diimplementasikan akan ada ambiguitas dalam tata bahasa ketika programmer berniat untuk menulis pernyataan koma-operator atau pemisah.
Singkatnya,
;
menandakan akhir dari sebuah pernyataan. Sebuahfor
lingkaran adalah kata kunci diikuti dengan daftar pernyataan opsional dikelilingi oleh()
. Pernyataan koma-operator memungkinkan penggunaan,
dalam satu pernyataan.sumber
for
loop secara eksplisit memungkinkan pernyataan (deklarasi) sebagai bagian pertama. (C ++ memungkinkan deklarasi fungsi-tengah, sebagai lawan dari pendahulunya C89). Anda tidak dapat menggeneralisasikan pernyataan seperti itu di seluruh bahasa, bahkan untuk 2 bahasa yang sedekat C dan C ++.for ( {<expression>}? ; {<expression>}? ; {<expression>}? ) <statement>
untuk C danfor ( for-init-statement; conditionopt ; expressionopt ) statement
untuk C ++ --- The ';' tidak hanya menandakan terminator pernyataan. A untuk loop tidak diikuti oleh pernyataan terlampir dalam ().Tidak ada pembalikan konseptual.
Titik koma di C mewakili lebih banyak divisi utama daripada koma. Mereka memisahkan pernyataan dan deklarasi.
Divisi utama dalam for loop adalah bahwa ada tiga ekspresi (atau deklarasi dan dua ekspresi) dan sebuah badan.
Koma yang Anda lihat di C untuk loop bukan bagian dari sintaks for for loop secara khusus. Mereka hanya manifestasi dari operator koma.
Koma adalah pemisah utama antara argumen dalam panggilan fungsi dan antara parameter dalam deklarasi fungsi, tetapi titik koma tidak digunakan. Untuk loop adalah sintaks khusus; itu tidak ada hubungannya dengan fungsi atau panggilan fungsi.
sumber
Mungkin ini adalah sesuatu yang spesifik untuk C / C ++, tetapi saya memposting jawaban ini, karena sintaks dari bahasa yang Anda jelaskan sebagian besar dipengaruhi oleh Sintaks C-.
Selain pertanyaan yang dijawab sebelumnya benar, dari sudut pandang teknis, itu juga karena dalam C (dan C ++) koma sebenarnya adalah operator , yang Anda bahkan dapat membebani . Menggunakan operator titik koma (
operator;()
) mungkin akan membuat lebih sulit untuk menulis kompiler, karena titik koma adalah terminator ekspresi aksiomatik.Apa yang membuat titik-temu ini adalah fakta, bahwa koma banyak digunakan sebagai pemisah di seluruh bahasa. Sepertinya operator koma adalah pengecualian, yang terutama digunakan untuk mendapatkan
for
-lompatan dengan beberapa kondisi bekerja, jadi apa masalahnya?Sebenarnya
operator,
dibangun untuk melakukan hal yang sama seperti dalam definisi, daftar argumen, dan sebagainya: Telah dibangun untuk memisahkan ekspresi - sesuatu yang,
tidak dapat dilakukan oleh konstruksi sintaksis . Ini hanya dapat memisahkan apa yang telah didefinisikan dalam standar.Namun titik koma tidak terpisah - itu berakhir . Dan ini juga yang membawa kita kembali ke pertanyaan awal:
Koma memisahkan ekspresi dalam tiga bagian loop, sedangkan titik koma mengakhiri bagian (inisialisasi, kondisi atau afterthought) dari definisi loop.
Bahasa pemrograman yang lebih baru (seperti C #) mungkin tidak memungkinkan overloading koma-operator, tetapi mereka kemungkinan besar tetap menggunakan sintaksis, karena mengubahnya terasa agak tidak wajar.
sumber
for
pernyataan,;
simbol digunakan sebagai pemisah. Ini memisahkan 3 bagian sintaksis dari pernyataan itu. Tidak ada titik koma ke-3 untuk "mengakhiri" daftar ekspresi progresif. Ini diakhiri oleh token yang berbeda -)
.Bagi saya mereka menggunakan makna yang kurang lebih mirip dengan arti linguistik mereka. Koma digunakan dengan daftar dan titik koma dengan bagian yang lebih terpisah.
Dalam
func(a, b, c)
kami memiliki daftar argumen.instruction1; instruction2; instruction3
mungkin daftar tetapi daftar instruksi yang terpisah dan independen.Sementara di
for ( init1, init2; condition; inc1, inc2 )
kami memiliki tiga bagian terpisah - daftar inisialisasi, kondisi dan daftar ekspresi kenaikan.sumber
Cara termudah untuk melihatnya adalah sebagai berikut:
aku s:
Dengan kata lain, mereka x = 0 thingy sebenarnya adalah pernyataan / instruksi daripada parameter. Anda memasukkan pernyataan di sana. Karenanya mereka dipisahkan oleh titik koma.
Bahkan tidak mungkin mereka dipisahkan oleh koma. Kapan terakhir kali Anda memasukkan hal-hal seperti x <10 sebagai parameter? Anda melakukannya jika Anda ingin komputer x <10 sekali dan masukkan hasil operasi itu sebagai parameter. Jadi di dunia koma Anda akan meletakkan x <10 jika Anda ingin meneruskan nilai x <0 ke suatu fungsi.
Di sini Anda menentukan bahwa program harus memeriksa x <10 setiap kali loop dilewatkan. Jadi itu instruksi.
x ++ jelas merupakan instruksi lain.
Itu semua instruksi. Jadi mereka dipisahkan oleh titik koma.
sumber
for
switch
ataureturn
di dalam definisi loop (yaitufor(int i = 0; if(i > 1024) { return; } ; switch (i % 3) { case 0; case 1: i++; case 2: i++; } ) { ... }
) --- Anda tidak bisa. Itu bukan pernyataan. Sebaliknya itu didefinisikan sebagaifor ( {<expression>}? ; {<expression>}? ; {<expression>}? ) <statement>
int i = 0
pasti BUKAN ekspresi. Seperangkat aturan yang menggambarkan ekspresi cukup rumit, mengingat apa yang bisa membentuk ekspresi, tetapi konstrukTYPE NAME = EXPRESSION
tidak cocok dengan aturan itu.