Saya bekerja dengan pengembang C ++ baru beberapa waktu lalu ketika dia mengajukan pertanyaan: "Mengapa nama variabel tidak bisa dimulai dengan angka?"
Saya tidak dapat menemukan jawaban kecuali bahwa beberapa angka dapat memiliki teks di dalamnya (123456L, 123456U) dan itu tidak akan mungkin terjadi jika kompiler memikirkan segala sesuatu dengan sejumlah karakter alfa adalah nama variabel.
Apakah itu jawaban yang benar? Apakah ada alasan lain?
string 2BeOrNot2Be = "that is the question"; // Why won't this compile?
0
yang mendorong 0 ke tumpukan. satu lagi adalah0=
yang memeriksa apakah 0 ada di stack.Jawaban:
Karena dengan demikian serangkaian digit akan menjadi pengidentifikasi yang valid serta nomor yang valid.
sumber
A
-F
dan diakhiri denganh
. Membuatku tersandung saat pertama kali aku mencoba mendefinisikan label untuk menunjukkan data musik untuk Two Part Invention # 13 Bach (nama logis?Bach
).Nah pikirkan tentang ini:
Apa itu 2.0? atau 42?
Petunjuk, jika Anda tidak mendapatkannya, d setelah angka berarti angka sebelum itu adalah literal ganda
sumber
d
bukan sufiks literal mengambang yang valid di C ++. Liter mengambang adalah ganda secara default, Anda dapat menggunakanf
ataul
jika Anda membutuhkan float atau literal ganda yang panjang.Ini adalah konvensi sekarang, tetapi dimulai sebagai persyaratan teknis.
Di masa lalu, parser bahasa seperti FORTRAN atau BASIC tidak memerlukan penggunaan spasi. Jadi, pada dasarnya, berikut ini identik:
dan
Sekarang anggaplah bahwa awalan angka diizinkan. Bagaimana Anda menafsirkan ini?
sebagai
atau sebagai
atau sebagai
Jadi, ini dibuat ilegal.
sumber
DO 10 I=1,50
dapat diuraikan secara ambigu sebagaiDO1 0I=1,50
[secara kebetulan, jika seseorang menggunakan periode alih-alih koma, pernyataan tersebut menjadi tugas untuk variabel floating-point bernamaDO10I
.Karena backtracking dihindari dalam analisis leksikal saat kompilasi. Variabel seperti:
kompiler akan segera tahu bahwa itu adalah pengidentifikasi ketika memenuhi huruf 'A'.
Namun variabel seperti:
kompiler tidak akan dapat memutuskan apakah itu angka atau pengidentifikasi hingga mencapai 'a', dan sebagai hasilnya perlu dilakukan penelusuran ulang.
sumber
Kompiler / pengurai / analisis leksikal sudah lama sekali bagi saya, tapi saya pikir saya ingat ada kesulitan dalam menentukan apakah karakter numerik dalam unit kompilasi mewakili literal atau pengidentifikasi.
Bahasa di mana ruang tidak signifikan (seperti ALGOL dan FORTRAN asli jika saya ingat dengan benar) tidak dapat menerima angka untuk memulai pengidentifikasi karena alasan itu.
Ini berjalan mundur - sebelum notasi khusus untuk menunjukkan penyimpanan atau basis numerik.
sumber
Saya setuju akan mudah untuk memungkinkan pengidentifikasi dimulai dengan angka. Satu atau dua orang telah menyebutkan bahwa Anda dapat mengatasi pembatasan ini dengan menambahkan garis bawah pada pengenal Anda, tetapi itu benar-benar jelek.
Saya pikir bagian dari masalah berasal dari sejumlah literal seperti 0xdeadbeef, yang membuatnya sulit untuk membuat aturan yang mudah diingat untuk pengidentifikasi yang dapat dimulai dengan angka. Salah satu cara untuk melakukannya mungkin dengan mengizinkan apa pun yang cocok dengan [A-Za-z _] + yang BUKAN kata kunci atau angka literal. Masalahnya adalah itu akan menyebabkan hal-hal aneh seperti 0xdeadpork diizinkan, tetapi tidak 0xdeadbeef. Pada akhirnya, saya pikir kita harus adil terhadap semua daging: P.
Ketika saya pertama kali belajar C, saya ingat merasa aturan untuk nama-nama variabel sewenang-wenang dan terbatas. Terburuk dari semuanya, mereka sulit untuk diingat, jadi saya menyerah mencoba mempelajarinya. Saya hanya melakukan apa yang terasa benar, dan itu bekerja dengan cukup baik. Sekarang saya sudah belajar banyak, sepertinya tidak terlalu buruk, dan akhirnya saya bisa mempelajarinya dengan benar.
sumber
Kemungkinan itu adalah keputusan yang datang karena beberapa alasan, ketika Anda menguraikan token, Anda hanya perlu melihat karakter pertama untuk menentukan apakah itu pengenal atau literal dan kemudian mengirimkannya ke fungsi yang benar untuk diproses. Jadi itu optimasi kinerja.
Pilihan lainnya adalah untuk memeriksa apakah itu bukan literal dan meninggalkan domain pengidentifikasi untuk menjadi alam semesta dikurangi literal. Tetapi untuk melakukan ini, Anda harus memeriksa setiap karakter dari setiap token untuk mengetahui cara mengklasifikasikannya.
Ada juga pengidentifikasi implikasi gaya yang seharusnya mnemonik sehingga kata-kata jauh lebih mudah diingat daripada angka. Ketika banyak bahasa asli sedang ditulis menetapkan gaya untuk beberapa dekade ke depan mereka tidak berpikir tentang mengganti "2" untuk "ke".
sumber
Nama variabel tidak dapat dimulai dengan angka, karena dapat menyebabkan beberapa masalah seperti di bawah ini:
berapa nilai c? adalah 4, atau 10!
contoh lain:
5 angka pertama, atau objek (operator). Ada masalah yang sama dengan 5 kedua.
Mungkin ada beberapa alasan lain. Jadi, kita tidak boleh menggunakan digit apa pun di awal nama variabel.
sumber
Penggunaan digit untuk memulai nama variabel membuat pengecekan kesalahan selama kompilasi atau interpertasi jauh lebih rumit.
Mengizinkan penggunaan nama variabel yang dimulai seperti angka mungkin akan menyebabkan masalah besar bagi perancang bahasa. Selama parsing kode sumber, setiap kali kompiler / juru bahasa menemui token yang dimulai dengan digit di mana nama variabel diharapkan, itu harus mencari melalui serangkaian besar, aturan rumit untuk menentukan apakah token itu benar-benar variabel, atau kesalahan . Kompleksitas tambahan yang ditambahkan ke parser bahasa mungkin tidak membenarkan fitur ini.
Sejauh yang saya ingat (sekitar 40 tahun), saya tidak berpikir bahwa saya pernah menggunakan bahasa yang memungkinkan penggunaan digit untuk memulai nama variabel. Saya yakin ini dilakukan setidaknya sekali. Mungkin, seseorang di sini benar-benar melihat ini di suatu tempat.
sumber
Seperti yang diketahui beberapa orang, ada banyak muatan historis tentang format yang valid untuk nama variabel. Dan desainer bahasa selalu dipengaruhi oleh apa yang mereka ketahui saat mereka menciptakan bahasa baru.
Yang mengatakan, hampir sepanjang waktu bahasa tidak memungkinkan nama variabel untuk mulai dengan angka adalah karena itu adalah aturan desain bahasa. Seringkali karena aturan sederhana membuat parsing dan lexing bahasa menjadi jauh lebih mudah. Namun, tidak semua perancang bahasa tahu bahwa inilah alasan sebenarnya. Alat lexing modern membantu, karena jika Anda mencoba mendefinisikannya diizinkan, mereka akan memberi Anda konflik penguraian.
OTOH, jika bahasa Anda memiliki karakter yang dapat diidentifikasi secara unik untuk nama variabel pemberita, adalah mungkin untuk mengaturnya agar mereka mulai dengan angka. Variasi aturan serupa juga dapat digunakan untuk memungkinkan spasi dalam nama variabel. Tetapi bahasa yang dihasilkan cenderung tidak terlalu mirip dengan bahasa konvensional yang populer.
Untuk contoh bahasa templating HTML yang cukup sederhana yang memungkinkan variabel untuk memulai dengan angka dan memiliki ruang yang disematkan, lihat Qompose .
sumber
Karena jika Anda mengizinkan kata kunci dan pengenal untuk memulai dengan karakter numerik, lexer (bagian dari kompiler) tidak dapat dengan mudah membedakan antara awal numerik literal dan kata kunci tanpa membuat jauh lebih rumit (dan lebih lambat).
sumber
Pembatasannya sewenang-wenang. Berbagai Lisps mengizinkan nama simbol untuk memulai dengan angka.
sumber
COBOL memungkinkan variabel untuk memulai dengan angka.
sumber
C ++ tidak dapat memilikinya karena desainer bahasa membuat aturan. Jika Anda ingin membuat bahasa Anda sendiri, Anda tentu bisa mengizinkannya, tetapi Anda mungkin akan mengalami masalah yang sama seperti yang mereka lakukan dan memutuskan untuk tidak mengizinkannya. Contoh nama variabel yang akan menyebabkan masalah:
0x, 2d, 5555
sumber
Salah satu masalah utama tentang konvensi sintaksis yang santai adalah bahwa ia memperkenalkan disonansi kognitif ke dalam proses pengkodean. Bagaimana Anda berpikir tentang kode Anda bisa sangat dipengaruhi oleh kurangnya kejelasan yang akan diperkenalkan ini.
Bukankah Dykstra yang mengatakan bahwa "aspek terpenting dari alat apa pun adalah pengaruhnya terhadap penggunanya"?
sumber
Mungkin karena memudahkan manusia untuk mengetahui apakah itu angka atau pengenal, dan karena tradisi. Memiliki pengidentifikasi yang dapat dimulai dengan digit tidak akan menyulitkan pemindaian leksikal sebanyak itu.
Tidak semua bahasa memiliki pengidentifikasi terlarang yang dimulai dengan angka. Di Forth, mereka bisa berupa angka, dan bilangan bulat kecil biasanya didefinisikan sebagai kata Forth (pengidentifikasi dasarnya), karena lebih cepat untuk membaca "2" sebagai rutinitas untuk mendorong 2 ke stack daripada mengenali "2" sebagai angka. yang nilainya 2. (Dalam memproses input dari programmer atau blok disk, sistem Forth akan membagi input sesuai dengan spasi. Akan mencoba untuk mencari token di kamus untuk melihat apakah itu kata yang didefinisikan, dan jika tidak akan berusaha menerjemahkannya menjadi angka, dan jika tidak akan menandai kesalahan.)
sumber
Misalkan Anda mengizinkan nama simbol dimulai dengan angka. Sekarang anggaplah Anda ingin memberi nama variabel 12345foobar. Bagaimana Anda membedakan ini dari 12345? Ini sebenarnya tidak terlalu sulit untuk dilakukan dengan ekspresi reguler. Masalahnya sebenarnya adalah salah satu dari kinerja. Saya tidak bisa menjelaskan mengapa ini sangat rinci, tetapi pada dasarnya bermuara pada fakta bahwa membedakan 12345foobar dari 12345 membutuhkan pengulangan. Ini membuat ekspresi reguler menjadi non-deterministik.
Ada penjelasan yang jauh lebih baik tentang ini di sini .
sumber
ifq
ataudoublez
tetapi tidakif
ataudouble
? Masalah mendasar dengan memungkinkan pengidentifikasi untuk memulai dengan angka adalah bahwa ada bentuk hex hexal dan angka floating-point yang seluruhnya terdiri dari karakter alfanumerik (bahasa akan menggunakan sesuatu seperti $ 1234 atau h'1234 bukan 0x1234, dan memerlukan angka seperti 1E23 untuk memasukkan titik, dapat menghindari masalah itu). Perhatikan bahwa upaya untuk regex-parsing C sudah bisa tersandung oleh hal-hal seperti0x12E+5
.mudah bagi kompilator untuk mengidentifikasi variabel menggunakan ASCII pada lokasi memori daripada angka.
sumber
Kompiler memiliki 7 fase sebagai berikut:
Mengulangi dihindari dalam fase analisis leksikal saat menyusun potongan kode. Variabel seperti Apple, kompiler akan segera tahu pengidentifikasi ketika bertemu dengan huruf 'A' pada fase Analisis leksikal. Namun, variabel seperti 123apple, kompiler tidak akan dapat memutuskan apakah itu angka atau pengidentifikasi sampai hits 'a' dan perlu mundur untuk masuk dalam fase analisis leksikal untuk mengidentifikasi bahwa itu adalah variabel. Tetapi tidak didukung di kompiler.
Saat Anda menguraikan token, Anda hanya perlu melihat karakter pertama untuk menentukan apakah itu pengenal atau literal dan kemudian mengirimnya ke fungsi yang benar untuk diproses. Jadi itu optimasi kinerja.
sumber
Saya pikir jawaban sederhana adalah bahwa hal itu bisa, batasannya adalah berdasarkan bahasa. Di C ++ dan banyak lainnya tidak bisa karena bahasa tidak mendukungnya. Itu tidak dibangun ke dalam aturan untuk memungkinkan itu.
Pertanyaannya adalah seperti menanyakan mengapa Raja tidak bisa memindahkan empat ruang sekaligus dalam Catur? Itu karena di Catur itu adalah langkah ilegal. Bisa di game lain pasti. Itu hanya tergantung pada aturan yang dimainkan.
sumber
Awalnya itu hanya karena lebih mudah untuk mengingat (Anda dapat memberikan lebih banyak makna) nama variabel sebagai string daripada angka meskipun angka dapat dimasukkan dalam string untuk meningkatkan makna string atau memungkinkan penggunaan nama variabel yang sama tetapi memilikinya ditunjuk memiliki makna atau konteks yang terpisah, tapi dekat. Misalnya loop1, loop2 dll akan selalu memberi tahu Anda bahwa Anda berada dalam satu loop dan / atau loop 2 adalah loop dalam loop1. Mana yang Anda inginkan (memiliki makna lebih) sebagai variabel: alamat atau 1121298? Mana yang lebih mudah diingat? Namun, jika bahasa tersebut menggunakan sesuatu untuk menyatakan bahwa itu bukan hanya teks atau angka (seperti $ dalam $ address) itu benar-benar tidak boleh membuat perbedaan karena itu akan memberitahu kompiler bahwa apa yang berikut harus diperlakukan sebagai variabel ( pada kasus ini).
sumber
Variabel dapat dianggap sebagai nilai juga selama waktu kompilasi oleh kompiler sehingga nilai dapat memanggil nilai lagi dan lagi secara rekursif
sumber
Mengulangi dihindari dalam fase analisis leksikal saat menyusun potongan kode . Variabel seperti Apple; , kompiler akan segera mengetahui pengidentifikasi ketika memenuhi karakter huruf 'A' dalam fase Analisis leksikal. Namun, variabel seperti 123apple; , compiler tidak akan dapat memutuskan apakah angka atau pengenalnya sampai hits 'a' dan perlu mundur untuk masuk dalam fase analisis leksikal untuk mengidentifikasi bahwa itu adalah variabel. Tetapi tidak didukung di kompiler.
Referensi
sumber
Tidak ada yang salah dengan itu ketika datang ke mendeklarasikan variabel.tapi ada beberapa ambiguitas ketika mencoba menggunakan variabel itu di tempat lain seperti ini:
biarkan 1 = "Halo dunia!" print (1) print (1)
cetak adalah metode umum yang menerima semua jenis variabel. jadi dalam situasi itu kompiler tidak tahu yang mana (1) pemrogram merujuk: 1 dari nilai integer atau 1 yang menyimpan nilai string. mungkin lebih baik bagi kompiler dalam situasi ini untuk memungkinkan untuk mendefinisikan sesuatu seperti itu tetapi ketika mencoba untuk menggunakan hal-hal yang ambigu ini, membawa kesalahan dengan kemampuan koreksi untuk bagaimana memperbaiki kesalahan itu dan menghapus ambiguitas ini.
sumber