Mengapa Anda harus menentukan tipe data saat mendeklarasikan variabel?

41

Dalam sebagian besar bahasa pengkodean (jika tidak semua) Anda perlu mendeklarasikan variabel. Misalnya dalam C # jika itu bidang angka maka

int PhoneNumber

Jika saya menggunakan bahasa Inggris normal saya tidak perlu mendeklarasikan PhoneNumbersebagai intmenggunakannya. Sebagai contoh jika saya meminta teman saya Sam untuk memberi saya nomor teleponnya saya katakan:

"Sam, beri aku nomor teleponnya"

Saya tidak akan mengatakannya

"Char (20) Sam beri aku nomor telepon int"

Mengapa kita harus menentukan tipe data sama sekali?

kontol smith
sumber
83
Itu karena bahasa Inggris memiliki pengetikan implisit - jadi yourPhoneNumber secara implisit diketik sebagai PhoneNumber - manusia juga memiliki alokasi memori dinamis ...;)
HorusKol
28
Anda dan Sam tahu bahwa nomor telepon terdiri dari angka dan Anda akan terkejut menemukan surat di dalamnya. Komputer tidak dan perlu diberi tahu.
Thorbjørn Ravn Andersen
16
Dan ketika saya mendengar angka seperti 1-800-JIMBO di film, pikiran saya adalah: Bagaimana angka itu ? Oo
muru
103
Anda seharusnya tidak mendeklarasikan nomor telepon sebagai int. Dalam sebagian besar bahasa pemrograman ini akan menghapus angka nol di depan.
Aron_dc
25
@HorusKol: manusia tidak hanya memiliki alokasi memori dinamis, tetapi juga pengumpul sampah yang sangat tidak
konservatif

Jawaban:

79

Dalam sebagian besar bahasa pengkodean (jika tidak semua) Anda perlu mendeklarasikan variabel.

[...]

Mengapa kita harus menentukan tipe data sama sekali?

Itu adalah dua pertanyaan independen:

  • Mengapa kita perlu mendeklarasikan variabel?
  • Mengapa kita perlu mendeklarasikan tipe?

Kebetulan, jawaban untuk keduanya adalah: kita tidak.

Ada banyak bahasa pemrograman yang diketik secara statis di mana Anda tidak perlu mendeklarasikan jenis. Kompiler dapat menyimpulkan tipe dari konteks sekitarnya dan penggunaannya.

Misalnya, di Scala bisa Anda katakan

val age: Int = 23

atau bisa dibilang begitu

val age = 23

Keduanya persis sama: kompiler akan menyimpulkan tipe Intdari ekspresi inisialisasi 23.

Demikian juga, di C♯, Anda dapat mengatakan salah satu dari ini, dan keduanya memiliki arti yang sama persis:

int age = 23;
var age = 23;

Fitur ini disebut inferensi tipe , dan banyak bahasa selain Scala dan C♯ memilikinya: Haskell, Kotlin, Ceylon, ML, F♯, C ++, sebut saja. Bahkan Java memiliki bentuk inferensi tipe terbatas.

Dalam bahasa pemrograman yang diketik secara dinamis, variabel bahkan tidak memiliki tipe. Jenis hanya ada secara dinamis saat runtime, bukan statis. Hanya nilai dan ekspresi yang memiliki tipe dan hanya saat runtime, variabel tidak memiliki tipe.

Misalnya dalam naskah ECMAS:

const age = 23;
let age = 23;

Dan terakhir, dalam banyak bahasa, Anda bahkan tidak perlu mendeklarasikan variabel sama sekali. misalnya di Ruby:

age = 23

Bahkan, contoh terakhir itu valid dalam sejumlah bahasa pemrograman. Baris kode yang sama persis juga akan bekerja dengan Python, misalnya.

Begitu,

  • bahkan dalam bahasa yang diketik secara statis di mana variabel memiliki tipe, Anda tidak perlu mendeklarasikannya,
  • dalam bahasa yang diketik secara dinamis, variabel tidak memiliki jenis, jadi jelas Anda bahkan tidak dapat mendeklarasikannya,
  • dalam banyak bahasa, Anda bahkan tidak perlu mendeklarasikan variabel
Jörg W Mittag
sumber
2
Plus satu untuk menjelaskan inferensi tipe dan pengetikan dinamis (pengikatan lanjut)
dcorking
36
Ini adalah info hebat tentang kesalahpahaman di balik pertanyaan, tetapi pertanyaan itu masih belum terjawab. Pertanyaannya, lebih tepatnya, mengapa kita harus menentukan tipe data ketika mendeklarasikan variabel dalam bahasa yang mengharuskan itu? Mengapa mereka dirancang sedemikian rupa? Ada jawaban bagus untuk pertanyaan itu, dan sementara menguraikan alternatif memperluas wawasan OP dan sangat bagus, itu tampaknya tidak lengkap bagi saya.
KRyan
7
@ KRyan: jika Anda ingin tahu mengapa perancang bahasa tertentu membuat pilihan desain bahasa tertentu, Anda harus bertanya kepada perancang bahasa itu, saya khawatir. Saya tidak bisa memberi tahu Anda mengapa para perancang C♯ memutuskan menentang inferensi tipe, dan saya juga tidak bisa memberi tahu Anda mengapa mereka kemudian berubah pikiran. Desain bahasa banyak dikritik dan sering kali tidak sesuai selera. Jika, OTOH, Anda ingin tahu tentang trade-off spesifik yang terlibat, jawabannya pada dasarnya akan dicetak ulang dari Jenis dan Bahasa Pemrograman Prof. Pierce yang terlalu luas untuk Stack Exchange.
Jörg W Mittag
2
JörgWMittag: seperti yang sudah dikatakan @KRyan, jawaban "Anda tidak perlu" tidak terlalu menarik (itu jelas sekali - banyak bahasa mengizinkan untuk menghilangkan deklarasi jenis dalam beberapa kasus). Pertanyaan "mengapa Anda ingin mendeklarasikan tipe" jauh lebih menarik dan lebih mencerminkan semangat dari pertanyaan awal (jawaban Anda mengingatkan saya pada lelucon: "di mana kita berada?" - "Anda berada di balon udara panas ! " ). Anda tidak perlu tahu apa yang dipikirkan oleh perancang bahasa tertentu pada saat itu, untuk memberikan beberapa alasan bagus yang mendukung deklarasi jenis.
jfs
1
@Zaibis: auto i = 1 // i is inferred to type int, vector<int> vec; auto itr = vec.iterator(); // itr is inferred to type vector<int>::iteratordan sebagainya. Jika Anda ingin tahu cara kerjanya, Anda dapat mencarinya di spec.
Jörg W Mittag
53

Ketika Anda menggunakan bahasa alami untuk merujuk ke informasi, itu tidak terlalu tepat, dan khususnya, tidak banyak berkomunikasi dengan orang lain tentang niat Anda. Masalah serupa terjadi ketika mencoba melakukan matematika dalam bahasa alami: itu tidak cukup tepat.

Pemrogramannya kompleks; kesalahan terlalu mudah didapat. Jenis adalah bagian dari sistem pemeriksaan yang dirancang untuk mencegah status program ilegal, dengan mendeteksi kondisi kesalahan. Bahasa yang berbeda menggunakan tipe yang berbeda: beberapa bahasa menggunakan tipe yang banyak untuk mendeteksi kesalahan pada waktu kompilasi. Hampir semua bahasa memiliki gagasan tentang tipe yang tidak kompatibel sebagai kesalahan runtime. Biasanya kesalahan jenis menunjukkan bug semacam dalam program. Ketika kami mengizinkan program untuk melanjutkan meskipun ada kesalahan, kami mungkin mendapatkan jawaban yang sangat buruk. Kami lebih suka menghentikan program daripada mendapatkan jawaban yang salah atau salah.

Dengan kata lain, tipe mengekspresikan kendala pada perilaku program. Kendala, ketika diberlakukan oleh beberapa mekanisme, memberikan jaminan. Jaminan semacam itu membatasi jumlah alasan yang diperlukan untuk memikirkan program, sehingga menyederhanakan tugas membaca dan memelihara program untuk programmer. Tanpa tipe, dan implikasi alat (yaitu kompiler) yang mendeteksi kesalahan tipe, beban pemrograman jauh lebih tinggi, dan dengan demikian, lebih mahal.

Memang benar bahwa (banyak) manusia dengan mudah membedakan antara nomor telepon Eropa, Amerika Serikat, dan internasional. Namun, komputer tidak benar-benar "berpikir", dan akan, jika diberi tahu, memutar nomor telepon amerika serikat di eropa, atau sebaliknya. Jenis, misalnya, adalah cara yang baik untuk membedakan antara kasus-kasus ini, tanpa harus mengajarkan komputer bagaimana "berpikir". Dalam beberapa bahasa, kita bisa mendapatkan kesalahan waktu kompilasi karena mencoba mencampur nomor telepon Eropa pada sistem telepon Amerika. Kesalahan itu memberi tahu kita bahwa kita perlu memodifikasi program kita (mungkin dengan mengubah nomor telepon menjadi urutan panggilan internasional, atau, dengan menggunakan nomor telepon di Eropa sebagai gantinya), bahkan sebelum kita mencoba menjalankan program.

Lebih jauh, karena komputer tidak berpikir, nama bidang atau variabel (mis. phonenumber), Tidak ada artinya bagi komputer. Untuk komputer, nama bidang / variabel itu hanya "blah123". Pikirkan bagaimana program Anda jika semua variabel "blahxxx". Astaga. Nah, itulah yang dilihat komputer. Menyediakan tipe memberi komputer firasat pada makna variabel yang tidak dapat disimpulkan dari namanya saja.

Lebih lanjut, seperti yang dikatakan @Robert, dalam banyak bahasa modern kita tidak perlu menentukan jenis sebanyak yang kita lakukan di masa lalu, karena bahasa seperti C # melakukan "type inference", yang merupakan seperangkat aturan untuk menentukan jenis yang tepat untuk variabel dalam konteks. C # hanya menyediakan inferensi tipe pada variabel lokal, tetapi tidak pada parameter formal, atau kelas atau bidang contoh.

Erik Eidt
sumber
4
RE bagian yang menyedihkan: Tidak mungkin untuk menyimpulkan jenis anggota yang dapat diakses publik (bidang publik, tanda tangan metode publik), karena Anda tidak dapat memprediksi kapan dan bagaimana itu akan digunakan. Juga, ketik anotasi adalah dokumentasi.
Sergio Tulentsev
Saya pikir Anda harus menyorot / tebal baris ini: Types are part of a system of checks that ...karena langsung menjawab OP pada Why do we have to specify data type at all?..
txtechhelp
Catatan: Anda menjawab dengan asumsi bahwa bahasa yang digunakan untuk menentukan jenis entah bagaimana lebih baik dalam menghindari kesalahan daripada bahasa pemrograman biasa. Jelas tidak begitu misalnya, pertimbangkan bahasa template C ++ yang Turing-complete (dan karenanya memungkinkan untuk mengekspresikan banyak pengecekan kesalahan) tetapi hampir tidak dapat dibaca dibandingkan dengan banyak bahasa Turing-complete lainnya seperti Haskell, Python, dan bahkan bagian lain dari C ++ itu sendiri. Tanyakan kepada diri Anda sendiri mengapa Anda tidak menggunakan bahasa pemrograman yang sama, untuk mengekspresikan pemeriksaan kesalahan sebagai bagian dari program Anda (ada jawaban yang baik dalam beberapa tetapi tidak semua kasus).
jfs
@SergioTulentsev Itu tidak benar - di F #, Anda dapat memiliki metode publik tanpa menentukan jenisnya secara eksplisit. Kompiler akan menyimpulkan tipe dari penggunaan di dalam metode. Misalnya, berikut ini adalah definisi metode publik yang valid: static member add x y = x + y, member x.Append s = x.Text + s. Dalam kasus pertama, xdan yakan disimpulkan sebagai intkarena penambahan. Dalam kasus kedua mereka akan menjadi apa pun yang valid tergantung pada jenis x.Text- jika itu adalah string, maka sakan menjadi stringjuga. Saya setuju bahwa anotasi jenis adalah dokumentasi.
Roujo
"Tipe lokal implisit, tipe antarmuka eksplisit" adalah cara banyak orang memprogram, bahkan dalam bahasa seperti Haskell yang memungkinkan Anda untuk menghilangkan (hampir) semua tipe sambil tetap membuat kompiler menyimpulkan tipe yang ketat. Ada banyak orang yang tidak menganggapnya sedih ketika sebuah bahasa memberlakukan praktik ini (seperti yang dilakukan C #).
Ben
29

Selain jawaban yang lain, ada satu hal yang harus dimasukkan. Ingat bahwa komputer hanyalah bit. Katakanlah saya memberi Anda byte:

26 3A 00 FF

Apa itu berarti ? Ini disimpan dengan cara ini oleh komputer, tetapi tanpa interpretasi apa pun, itu hanya bit . Bisa jadi 4 karakter ascii. Itu bisa berupa bilangan bulat. Bisa jadi beberapa byte dalam sebuah array. Itu bisa menjadi bagian dari suatu objek. Ini bisa menjadi pointer ke tempat video kucing itu buffering. Hampir semua bahasa pemrograman dari assembly ke atas membutuhkan sesuatu untuk mengetahui bagaimana menafsirkan bit untuk membuat mereka melakukan perhitungan yang bermakna.

Dan karena komputer tidak dapat mengetahui arti dari bit-bit itu, Anda perlu mengatakannya - baik secara eksplisit melalui anotasi jenis, atau secara implisit melalui mekanisme inferensi tipe yang disebutkan dalam jawaban lain.

Telastyn
sumber
10
Cukup benar, tetapi untuk benar-benar mengejutkan pikiran Anda, sadari bahwa komputer tidak pernah mampu memahami apa arti bit-bit itu — bahkan ketika Anda mengatakannya lebih banyak jenis anotasi. Penjelasan Anda hanya bisa berubah menjadi lebih banyak angka hex, untuk "memperjelas" angka hex pertama. Pentingnya semua diciptakan oleh orang-orang untuk memasukkan niat ke dalam elektronik dan membuat mereka melakukan apa yang kita inginkan. Sekarang, katakan "terima kasih" kepada seorang insinyur. :)
Wildcard
1
Saya menghabiskan bertahun-tahun pemrograman pada mainframe. Dengan PL / 1 jawaban ini sangat masuk akal. Cukup teratur, kita akan menggunakan penyimpanan berbasis berdasarkan pointer yang diatur ke alamat variabel lain dari tipe data yang berbeda untuk mengakses byte dengan cara yang berbeda. Misalnya PL / 1 tidak mendukung bidang angka biner 1 byte, tetapi kami mendasarkan variabel 1 karakter di alamat untuk memungkinkan kami menyimpan array 6 byte yang menyimpan 6 bidang biner byte tunggal (dalam hal ini memungkinkan kami untuk menyimpan 6 byte per alamat - yang penting saat penyimpanan mahal).
Kickstart
1
Komputer mampu memahami banyak kemungkinan tetapi bahkan kompiler yang pandai pun perlu memahami konteksnya. Tidak sama dengan angka 0 atau "0". Atau String "31 Des" akan dipesan sebelum "1 Mei" diperlakukan sebagai String tetapi tidak jika diperlakukan sebagai Tanggal. Atau ambil 5/2. Ini 2 sebagai entri tetapi 2,5 sebagai ganda. Juga, jenisnya adalah langkah pengamanan terhadap konversi yang tidak diinginkan. Null, NaN, dan pembulatan atau luapan juga bisa menjadi masalah. Bahasa yang diketik dengan kuat dan statis memiliki beberapa kelebihan. Misalnya, kompiler membantu Anda mendeteksi masalah saat melakukan refactoring.
Borjab
1
@ Borjab Apakah maksud Anda "Ini adalah 2 sebagai bilangan bulat "?
Richard Everett
1
@RichardEverett Tentu saja itu adalah lapsus. Terima kasih tetapi terlambat untuk mengeditnya.
Borjab
23

Jawaban mengapa komputer membutuhkan informasi ini berkaitan dengan Representasi Data .

Nama "tipe data" adalah referensi ke aturan yang membantu komputer menyimpan dan mengambil informasi dari keadaan mentah 0 dan 1 dalam memori komputer.

Sebagai contoh, karakter ASCII 8-bit biasa Anda akan disimpan dalam memori komputer (baik RAM atau Disk) sebagai 01000001(karakter huruf besar "A", kode ASCII 65) atau 00001000(tanda persen), atau kombinasi 0 dan 1 dalam 8 bit itu.

Untuk contoh lain, beberapa bilangan bulat 8-bit unsigned dapat disimpan sebagai 00000101(angka 5) atau 00001000(angka 8)

Perhatikan bagaimana representasi biner dari 8 dan karakter% mungkin sama, tetapi mereka memiliki arti yang berbeda karena tipenya berbeda.

Bahkan bahasa yang menyimpulkan tipe data, mereka mungkin tidak memiliki aturan bahwa "semua jenis variabel harus dideklarasikan oleh programmer", mereka memiliki aturan seperti "jika rangkaian karakter Anda dilampirkan dalam tanda kutip, itu adalah string" dan lebih banyak aturan untuk setiap tipe data.

Jadi bahkan ini memerlukan tipe data untuk memahami apa arti 0 dan 1, sehingga mereka dapat misalnya melakukan fungsi penggabungan string jika Anda mencoba untuk "menambahkan" dua karakter, atau melakukan penambahan bilangan bulat jika Anda mencoba menambahkan dua bilangan bulat .

Dalam cerita Anda juga, katakanlah Anda tidak meminta nomor telepon Sam tetapi Sam memberi Anda selembar kertas yang bertuliskan "1123581321". Anda tidak bisa memastikan apakah Sam hanya penggemar delapan angka Fibonacci pertama, atau jika itu adalah nomor telepon. Untuk membuat tebakan, Anda harus mempertimbangkan konteks dan isyarat yang Anda miliki, seperti mungkin Anda meminta nomor telepon Sam kemarin, atau catatan bertuliskan "Panggil Aku", atau jika Anda menghitung angka dan menemukan itu cocok dengan pola sebagian besar nomor telepon. Hanya dengan begitu Anda akan tahu bahwa itu adalah nomor telepon yang dapat Anda panggil dan bukan angka yang akan Anda masukkan ke kalkulator.

Perhatikan bagaimana petunjuk ini yang membuat Anda menebak bahwa nomor itu adalah nomor telepon mirip dengan bagaimana petunjuk mengarahkan bahasa komputer yang tidak memerlukan deklarasi untuk menyimpulkan jenis nilai.

Peeyush Kushwaha
sumber
3
Ini jawaban terdekat. Itu semua ada hubungannya dengan memori. Anda mendeklarasikan tipe sehingga kompiler tahu berapa banyak memori untuk aplikasi harus meminta saat runtime. Mengetahui bagaimana bit harus ditafsirkan adalah hal sekunder.
Greg Burghardt
@GregBurghardt benar. Untuk membuat rasa bit sudah ada serta menempatkan bit ada di tempat pertama setelah mengkonversi data yang diberikan ke biner sesuai dengan tipe data.
Peeyush Kushwaha
10

Dalam beberapa bahasa, Anda tidak harus menentukan tipe data.

Bahasa yang mendukung inferensi tipe biasanya dapat mengetahui tipe data dari penggunaan Anda. Sebagai contoh,

var name = "Ali"

diketik secara internal sebagai string, karena nilainya dikelilingi oleh tanda kutip.

Beberapa bahasa tidak mengharuskan Anda untuk mendeklarasikan variabel; variabel dibuat saat pertama kali digunakan. Namun, itu dianggap sebagai praktik terbaik untuk secara spesifik mendeklarasikan variabel Anda, karena sejumlah alasan penting; sebagian besar karena melakukannya dengan lebih baik mengekspresikan niat Anda.

Robert Harvey
sumber
5
The var name = "Ali"gaya sebenarnya umum untuk yang modern statis bahasa diketik. Dalam bahasa yang diketik secara statis, jenisnya tetap pada saat pembuatan, tetapi masih dapat ditentukan oleh penginisialisasi. Definisi bahasa yang diketik secara dinamis adalah bahwa tipe melampirkan nilai, bukan variabel. Oleh karena itu, menetapkan nilai ke variabel menentukan tipe variabel juga.
MSalters
@ MSalters: Saya membuat sedikit penyesuaian pada kata-katanya.
Robert Harvey
5
Ironi di sini adalah ini termasuk C # dengan sintaks yang tepat ini.
Derek Elkins
1
@MSalters Menetapkan nilai ke variabel karena itu menetapkan tipe variabel juga. Atau bahwa variabel tidak memiliki tipe bawaan dan penerjemah akan mencoba untuk menerapkan operasi apa pun dengan nilai variabel. Apakah ada bahasa yang diketik secara dinamis di mana kode seperti berikut (Javascript) tidak akan diizinkan var x = 5; x = "";karena pernyataan pertama menyebabkan xmemiliki jenis "Nomor" yang terkait x? Semacam konflik dengan pengetikan dinamis . Dan jika tidak, efek apa yang dimiliki oleh tipe yang terkait dengan variabel, di luar tipe asosiasi dengan nilai?
Zev Spitz
1
@ ZevSpitz: Jenis pertama dari sistem tidak diketik secara dinamis, tetapi tidak diketik sama sekali. Contoh Javascript Anda tidak diketik secara dinamis, justru karena jenis Angka tidak dapat berubah. Dalam bahasa yang diketik secara dinamis, x = "";mengubah tipe x ke string, bahkan jika itu adalah angka sebelumnya.
MSalters
9

Karena itulah yang ditentukan oleh desain bahasa. Jadi untuk menjawab pertanyaan Anda, kami perlu melihat maksud di balik pengetikan eksplisit dalam bahasa seperti C # dan C ++. (Ya, C # melakukannya karena C ++ melakukannya karena C melakukannya, jadi kita perlu melihat maksudnya saat itu).

Pertama, pengetikan eksplisit dan statis memberikan ketelitian dalam pengkodean - menetapkan variabel sebagai bilangan bulat berarti bahwa kompiler dan perangkat lunak harus terkejut dan melemparkan kesalahan saat Anda menetapkan karakter atau string ke variabel. Pengetikan dinamis dapat menyebabkan sakit kepala bagi yang tidak waspada (cukup melihat pendekatan PHP atau javascripts untuk kebenaran hal-hal seperti array dan string kosong).

Anda dapat memiliki statis dengan pengetikan implisit - menginisialisasi variabel sebagai string berarti bahwa variabel hanya boleh berupa string, tetapi perasaan saya adalah bahwa ini dapat menyebabkan masalah bagi manusia membaca kode (saya cenderung menganggap pengetikan dinamis ketika ada pengetikan implisit ).

Juga, dalam beberapa bahasa, dimungkinkan untuk menulis sesuatu seperti kodesemu ini untuk menginisialisasi kelas dari input string:

PhoneNumber phoneNumber = "(61) 8 8000 8123";

Kedua, pengetikan eksplisit juga sejalan dengan alokasi memori. Sebuah int selalu begitu banyak byte. Nomor telepon begitu banyak byte. Kompiler dapat menetapkan blok memori ukuran yang sesuai yang kemudian dapat digunakan kemudian tanpa harus melihat berapa banyak ruang yang dibutuhkan ketika Anda menetapkan nilai.

PhoneNumber phoneNumber;
...
phoneNumber = "some value from somewhere";

Akhirnya, ini menghilangkan kebingungan ... apakah 123 bilangan bulat atau bilangan bulat yang tidak ditandatangani? Mereka membutuhkan jumlah byte yang sama, tetapi nilai maksimum yang disimpan dalam variabel jenis apa pun sangat berbeda ...

Ini tidak mengatakan bahwa eksplisit lebih baik daripada implisit - tetapi desain bahasa bergantung pada jenis-jenis pilihan ini, dan C # akan bekerja secara berbeda dengan pengetikan implisit. PHP dan javascript akan bekerja secara berbeda dengan pengetikan eksplisit.

HorusKol
sumber
5

Karena Sam lebih pintar daripada kompiler. Misalnya, ketika Anda mengatakan memberi saya nomor telepon, Anda tidak menentukan apakah Anda ingin awalan negara atau kode area apakah itu nomor kerja di mana hanya 4 digit terakhir diperlukan. Juga, Anda jika Anda meminta nomor gabungan pizza lokal, Anda akan dapat berurusan dengan jawaban "pizza4u".

Sam, mencari tahu dari konteksnya. Sementara kompiler juga dapat mengetahuinya dari konteks, Sam akan lebih baik dalam hal itu (dan mampu mengganggu proses untuk meminta klarifikasi).

Ada dua pendekatan dasar untuk tipe dan variabel, baik variabel memiliki tipe, di mana tindakan kasus yang tidak diizinkan oleh tipe dilarang dan mencegah kompilasi, atau nilai memiliki tipe dan tindakan yang tidak diizinkan oleh tipe ditangkap saat runtime.

Setiap pendekatan memiliki kelebihan dan kekurangan. Secara umum, penulis kompiler mencoba untuk meminimalkan kerugian dan memaksimalkan keuntungan. Itulah sebabnya C # misalnya memungkinkan var phoneNumber = GetPhoneNumber();dan akan menyimpulkan jenis phoneNumber dari tanda tangan GetPhoneNumber. Itu berarti Anda harus mendeklarasikan tipe untuk metode, tetapi bukan variabel yang menerima hasilnya. Di sisi lain, ada berbagai jenis proyek petunjuk / penegakan javascript. Semuanya adalah tradeoff.

jmoreno
sumber
3

Ini masalah cara data disimpan. Interaksi Anda dengan Sam akan membuat perbandingan yang lebih baik jika Anda bertanya sehingga Anda dapat menuliskannya tetapi hanya memiliki kertas bernilai delapan karakter.

"Sam, beri aku nomor teleponnya."

"5555555555"

"Oh, tidak, aku kehabisan kertas. Kalau saja aku tahu sebelumnya berapa banyak data yang aku minta aku bisa mempersiapkan diri dengan lebih baik!"

Jadi sebagai gantinya, sebagian besar bahasa membuat Anda mendeklarasikan suatu jenis, sehingga ia akan tahu dan mempersiapkan sebelumnya:

"Sam, berapa lama nomor teleponnya?"

"Sepuluh karakter."

"Oke, kalau begitu biarkan aku mengambil selembar kertas yang lebih besar. Sekarang beri aku nomor telepon."

"5555555555"

"Mengerti! Terima kasih, Sam!"

Itu menjadi lebih hairier ketika Anda melihat cara mendasar sebenarnya bahwa data disimpan. Jika Anda seperti saya, Anda memiliki buku catatan dengan catatan lain-lain, angka-angka hanya dicoret, tidak ada konteks atau pelabelan untuk apa pun, dan Anda tidak tahu apa arti semua itu tiga hari kemudian. Ini juga masalah bagi komputer. Banyak bahasa memiliki tipe "int" (int, panjang, pendek, byte) dan "float" (float, double). Mengapa itu perlu?

Baiklah pertama-tama mari kita lihat bagaimana sebuah integer disimpan, dan umumnya direpresentasikan di dalam komputer. Anda mungkin menyadari bahwa pada tingkat dasar, semuanya biner (1 dan 0). Binary sebenarnya adalah sistem angka yang bekerja persis seperti sistem angka desimal kami. Dalam desimal, Anda menghitung 0 hingga 9 (dengan nol terkemuka yang tersirat tak terhingga yang tidak Anda tulis), lalu Anda putar kembali ke 0 dan menambah angka berikutnya sehingga Anda memiliki 10. Anda mengulangi hingga berguling dari 19 hingga 20, ulangi sampai Anda berguling dari 99 hingga 100, dan seterusnya.

Biner tidak berbeda, kecuali bahwa bukannya 0 hingga 9, Anda menghitung 0 hingga 1. 0, 1, 10, 11, 100, 101, 110, 111, 1000. Jadi ketika Anda mengetikkan 9, dalam memori yang direkam dalam biner sebagai 1001. Ini adalah angka aktual. Itu dapat ditambahkan, dikurangi, dikalikan, dll, persis dalam bentuk itu. 10 + 1 = 11. 10 + 10 = 100 (gulung 1 ke 0 dan bawa 1). 11 x 10 = 110 (dan setara, 11 + 11 = 110).

Sekarang di memori aktual (termasuk register), ada daftar, larik, apa pun yang Anda ingin menyebutnya, bit (potensial 1 atau 0 ') tepat di samping satu sama lain, yaitu bagaimana ia membuat bit-bit ini diatur secara logis untuk membuat angka lebih besar dari 1. Masalahnya adalah, apa yang Anda lakukan dengan desimal? Anda tidak bisa begitu saja memasukkan perangkat keras di antara dua bit dalam register, dan akan terlalu mahal untuk menambahkan "bit desimal" di antara setiap pasangan bit. Jadi apa yang harus dilakukan?

Anda menyandikannya. Secara umum, arsitektur CPU atau perangkat lunak akan menentukan bagaimana hal ini dilakukan, tetapi satu cara yang umum adalah menyimpan tanda (+ atau -, umumnya 1 negatif) di bit pertama register, mantissa (nomor Anda bergeser Namun berkali-kali perlu untuk menghilangkan desimal) untuk jumlah bit X berikut, dan eksponen (berapa kali Anda harus menggesernya) untuk sisanya. Ini mirip dengan notasi ilmiah.

Mengetik memungkinkan kompiler mengetahui apa yang dilihatnya. Bayangkan Anda menyimpan nilai 1.3 dalam register 1. Kami hanya akan datang dengan skema pengkodean mewah kami sendiri di sini, 1 bit untuk tanda, 4 untuk mantissa, 3 untuk eksponen (1 bit untuk tanda, 2 untuk besarnya). Ini adalah angka positif, jadi tandanya positif (0). Mantera kita adalah 13 (1101) dan eksponen kita adalah -1 (101 (1 untuk negatif, 01 = 1)). Jadi kita menyimpan 01101101 dalam register 1. Sekarang kita tidak mengetik variabel ini, jadi ketika runtime mulai menggunakannya, ia mengatakan "yakin, ini adalah bilangan bulat mengapa tidak" jadi ketika mencetak nilai yang kita lihat 109 (64 + 32 + 8 + 4 + 1), yang jelas tidak benar.

Namun, tidak semua bahasa mengharuskan Anda mengetik secara eksplisit. C # memiliki kata kunci "var" yang menyebabkan tipe variabel ditafsirkan pada waktu kompilasi, dan bahasa lain seperti Javascript diketik secara dinamis sepenuhnya, ke titik di mana Anda dapat menyimpan integer dalam suatu variabel, kemudian menetapkannya ke boolean, lalu menetapkan kembali ke string dan bahasa melacak semuanya.

Tetapi jauh lebih mudah pada kompiler, interpreter, atau runtime - dan seringkali menghasilkan program yang lebih cepat karena tidak perlu menghabiskan sumber daya berharga untuk mengetik semuanya - untuk bertanya kepada Anda, programmer, seperti apa data yang Anda berikan.

Devsman
sumber
2

Ada bahasa pemrograman di mana Anda tidak perlu mendeklarasikan tipe data untuk variabel Anda. Bahkan ada bahasa pemrograman di mana Anda tidak perlu mendeklarasikan variabel sebelumnya; Anda bisa langsung menggunakannya .

Masalahnya dengan tidak mendeklarasikan nama variabel adalah jika Anda secara tidak sengaja salah mengeja nama variabel, Anda sekarang secara tidak sengaja membuat variabel baru yang sama sekali tidak terkait. Jadi, ketika Anda menjalankan program Anda, Anda tidak tahu mengapa sih yang variabel Anda mengatur tiba-tiba tidak ada di dalamnya ... Sampai, setelah berjam-jam debugging, Anda sadar bahwa Anda mengetik nama yang salah terkutuk! GRRR !!

Jadi mereka membuatnya sehingga Anda harus mendeklarasikan nama variabel yang akan Anda gunakan sebelumnya. Dan sekarang ketika Anda salah mengetik nama, Anda mendapatkan kesalahan waktu kompilasi, yang segera memberi tahu Anda persis di mana bug itu berada, bahkan sebelum program Anda berjalan. Bukankah itu jauh lebih mudah?

Kesepakatan yang sama dengan tipe data. Ada bahasa pemrograman di mana Anda tidak perlu mendeklarasikan jenis benda apa yang seharusnya. Jika Anda memiliki customervariabel yang sebenarnya hanya nama pelanggan, bukan seluruh objek pelanggan, mencoba mengambil alamat pelanggan dari string biasa ... tidak akan berfungsi. Seluruh titik mengetik statis adalah bahwa program ini tidak dapat dikompilasi; itu akan dengan keras mengeluh, menunjuk ke tempat yang tepat di mana masalahnya. Itu jauh lebih cepat daripada menjalankan kode Anda dan mencoba mencari tahu mengapa itu tidak bekerja.

Semua ini adalah fitur untuk memberi tahu kompiler apa yang ingin Anda lakukan, sehingga dapat memeriksa apa yang sebenarnya Anda lakukan dan memastikannya masuk akal. Itu memungkinkan kompiler menemukan bug secara otomatis untuk Anda, yang merupakan masalah besar.

(Jauh di masa lalu, Anda tidak perlu mendeklarasikan subrutin . Anda hanya perlu GOSUBke nomor baris tertentu. Jika Anda ingin meneruskan informasi antar subrutin, Anda akan menetapkan variabel global tertentu, hubungi subrutin Anda, dan kemudian memeriksa lainnya variabel ketika subrutin kembali. Tapi itu membuatnya mudah untuk lupa menginisialisasi salah satu parameter. Jadi sekarang hampir semua bahasa pemrograman modern menuntut Anda mendeklarasikan parameter aktual apa yang diambil subrutin, sehingga kami dapat memeriksa Anda telah menentukan semuanya. )

Matematika Matematika
sumber
1
Di C ++ Anda bisa meletakkan "auto x = 1" dan ia tahu itu int. otomatis y = 1.2; otomatis z = 'Z'; dll
QuentinUK
@ QuentinUK Di C #, Anda dapat menempatkan var x=1dengan hasil yang serupa. Tapi itu bukan apa-apa; di Haskell, Anda dapat menulis seluruh program Anda tanpa tanda tangan jenis sama sekali, namun semuanya diketik secara statis, dan Anda masih mendapatkan kesalahan jika Anda membuat kesalahan ... (Meskipun tidak sepenuhnya mainstream.)
MathematicalOrchid
@ QuentinUK Tetapi jika Anda menulis for (auto i=0; i<SomeStdVector.size(); ++i)linter Anda akan mengeluh karena menyimpulkan jenis yang ditandatangani dan Anda melanjutkan untuk membandingkannya dengan jenis yang tidak ditandatangani. Anda harus menulis auto i=0ul(memasukkan informasi jenis secara eksplisit lagi, jadi semestinya hanya menulis size_t i=0di tempat pertama).
dmckee
1

Jika saya menggunakan bahasa Inggris normal saya tidak perlu mendeklarasikan PhoneNumber sebagai int untuk menggunakannya. Sebagai contoh jika saya meminta teman saya Sam untuk memberi saya nomor teleponnya saya katakan:

"Sam, beri aku nomor teleponnya"

Saya tidak akan mengatakan>

"Char (20) Sam beri aku nomor telepon int"

Mengapa kita harus menentukan tipe data sama sekali?

Mampir ke MathOverflow atau Theoretical Computer Science dan bacalah sejenak untuk mendapatkan ide tentang bagaimana manusia berkomunikasi alogrithm satu sama lain ketika mereka ingin memastikan bahwa tidak ada kemungkinan kesalahpahaman. Atau baca standar untuk beberapa bahasa pemrograman dewasa.

Anda akan menemukan bahwa mendefinisikan jenis nilai apa yang diizinkan untuk suatu istilah adalah bagian dari praktik komunikasi yang sangat tepat bahkan dari manusia ke manusia.

Apa yang Anda perhatikan adalah bahwa interaksi sehari-hari cukup teratur dan manusia cukup toleran terhadap kesalahan, sehingga kesalahpahaman tentang nomor telepon umumnya dihindari oleh pengetahuan bersama para peserta.

Tetapi pernahkah Anda mencoba mencatat nomor telepon seseorang di negara lain? Apakah mereka memberi tahu Anda secara eksplisit berapa kali untuk mendorong nol untuk sampai ke pengalamatan internasional? Apakah mereka memberi tahu Anda kode negara mereka? Apakah Anda mengenalinya? Berapa angka yang Anda harapkan? Berapa banyak yang kamu dapat? Apakah Anda tahu cara mengelompokkan digit? Atau bahkan jika pengelompokan memiliki makna?

Tiba-tiba masalahnya jauh lebih sulit dan Anda mungkin lebih berhati-hati untuk memeriksa secara eksplisit bahwa nomor yang diterima dipahami dengan cara yang dimaksud pengirim.

dmckee
sumber
0

Alasan lain untuk menyatakan tipe adalah efisiensi. Sementara integer dapat disimpan dalam 1 byte, atau 2 byte, atau 4, sebuah program yang menggunakan sejumlah besar variabel mungkin menggunakan 4 kali memori yang dibutuhkan, tergantung pada apa yang sedang dilakukan. Hanya pemrogram yang tahu apakah ruang penyimpanan yang lebih kecil layak, sehingga ia dapat mengatakannya dengan menyatakan jenisnya.

Juga, objek yang diketik secara dinamis memungkinkan banyak jenis yang mungkin, dengan cepat. Itu bisa menimbulkan beberapa overhead "di bawah tenda", memperlambat program dibandingkan dengan bertahan dengan satu jenis selama ini.

donjuedo
sumber
0

Sejumlah bahasa pemrograman awal (terutama Fortran) tidak mengharuskan Anda mendeklarasikan variabel sebelum digunakan.

Ini menyebabkan sejumlah masalah. Salah satu yang sangat jelas adalah bahwa kompiler tidak lagi dapat menangkap kesalahan tipografi sederhana hampir sama andal. Jika Anda memiliki kode yang seharusnya mengubah variabel yang ada, tetapi memiliki kesalahan ketik, Anda masih memiliki kode yang sah yang baru saja membuat (dan menetapkan nilai untuk) variabel baru:

longVariableName = 1

// ...

longVaraibleName = longvariableName + anotherLongVariableName

Sekarang, melihat ini secara terpisah, dengan saya telah menyebutkan salah ketik sebagai sumber masalahnya, mungkin cukup mudah untuk menemukan kesalahan ketik dan masalahnya di sini. Dalam program yang panjang, di mana ini terkubur di tengah banyak kode lainnya, jauh lebih mudah untuk dilewatkan.

Bahkan saat ini dengan banyak bahasa yang diketik secara dinamis, Anda masih dapat dengan mudah mendapatkan masalah dasar yang sama. Beberapa memiliki beberapa fasilitas untuk memperingatkan Anda jika Anda menetapkan variabel, tetapi tidak pernah membacanya (yang secara heuristik menangkap beberapa masalah seperti ini) keduanya tidak memiliki hal-hal seperti itu.

Jerry Coffin
sumber
0

Ketika Anda mendeklarasikan variabel apa pun, beberapa ruang dialokasikan dalam memori ,, tetapi mesin (komputer dalam kasus ini) belum tahu bahwa berapa banyak ruang yang harus dialokasikan untuk variabel itu.

Contoh: - Anda membuat program yang meminta pengguna untuk memasukkan nomor apa pun, dalam hal ini Anda harus menentukan tipe data untuk menyimpan nomor itu, jika tidak, mesin tidak dapat menilai dengan sendirinya bahwa ia harus mengalokasikan 2 byte atau 2 gigabyte , jika ia mencoba untuk melakukan alokasi dengan sendirinya maka dapat mengakibatkan penggunaan memori yang tidak efisien .. Di sisi lain, jika Anda menentukan tipe data dalam program Anda, maka setelah kompilasi mesin akan mengalokasikan ruang yang tepat sesuai dengan kebutuhan.

Atul170294
sumber
ini tampaknya tidak menawarkan sesuatu yang substansial atas poin yang dibuat dan dijelaskan dalam 11 jawaban sebelumnya
nyamuk
1
Anda harus sekali lagi membaca semua jawaban dengan seksama dan melihat bahwa saya telah mencoba menjawab pertanyaan ini dengan cara yang jauh lebih sederhana yang orang dapat dengan mudah mengerti.
Atul170294
Saya baru saja memeriksa ulang tiga jawaban terbaru yang diposting sekitar satu jam sebelum yang satu ini dan ketiganya tampaknya membuat poin yang sama dan menurut bacaan saya menjelaskannya dengan cara yang lebih sederhana daripada di sini
nyamuk
Meskipun saya tidak menjawab untuk hadiah suara Anda, tetapi saya pikir Anda harus mengetahui satu hal, Anda harus menurunkan pilihan jawaban karena dapat memberikan informasi yang tidak berguna atau salah dan jika berisi sesuatu yang menyinggung. Semua jawaban yang memiliki informasi yang paling berguna dan relevan akan mendapatkan jumlah upvotes yang lebih tinggi yang cukup untuk membedakan antara jawaban, jawaban yang baik dan jawaban terbaik. Aktivitas kekanak-kanakan Anda untuk merendahkan jawaban tanpa alasan kuat hanya akan membuat orang lain enggan membagikan pendapat mereka yang menurut mereka mungkin berguna bagi orang lain
Atul170294
1
Jawaban Anda kemungkinan besar tidak dipilih karena tidak benar. Pengetikan statis tidak diperlukan untuk membantu manajemen memori. Ada banyak bahasa yang memungkinkan pengetikan dinamis, dan bahasa / lingkungan tersebut dapat menangani masalah manajemen memori yang Anda sebutkan.
Jay Elston