04. Menelusuri program secara manual

Ada dua cara untuk mengetahui apa yang dilakukan sebuah program. Jalankan dan amati, atau jadilah komputer: baca satu baris demi satu baris, berurutan, dan kerjakan setiap baris di atas kertas. Keterampilan kedua itu disebut penelusuran (tracing), hal paling berguna di bagian buku ini. Programmer yang bisa menelusuri kode bisa membacanya, memprediksinya, dan menemukan bug tanpa pernah menjalankannya.

Menjadi komputer, pelan-pelan

Di Bab 01 kamu belajar bahwa komputer mengerjakan persis apa yang diperintahkan, berurutan, dari atas ke bawah. Menelusuri adalah pekerjaan yang sama, dengan tangan. Baris demi baris. Jangan melompat. Jangan berasumsi. Kalau sebuah baris mengubah nilai, coret nilai lama dan tulis yang baru.

Yang membuat cara ini bisa diandalkan adalah tabel penelusuran (trace table): kisi dengan satu kolom per variabel dan satu baris untuk setiap perubahan. Kamu mengisinya sambil membaca.

Contoh penelusuran

Berikut program pendek. Jangan dijalankan. Baca baris demi baris sambil mengisi tabel.

a := 5
b := 3
total := a + b
a = a + 1
fmt.Println(total)
fmt.Println(a)

Baris dengan :=, seperti x := ..., mendeklarasikan nama baru dan mengisinya dengan nilai. Baris dengan = saja, seperti x = ..., memperbarui nama yang sudah ada. Tabelnya, satu baris demi satu baris:

Baris a b total
a := 5 5
b := 3 5 3
total := a + b 5 3 8
a = a + 1 6 3 8

Pada fmt.Println(total), tabel menunjukkan total bernilai 8. Pada fmt.Println(a), tabel menunjukkan a bernilai 6. Jadi outputnya:

8
6

Yang perlu diperhatikan: total dihitung sekali, pada baris ketiga, ketika a masih 5. Mengubah a setelahnya tidak menghitung ulang total. Tabel membuat hal itu jelas: total tidak pernah berubah setelah baris yang mengisinya. Penelusuran mengungkapnya; menebak menyembunyikannya.

Menelusuri perulangan

Perulangan menjalankan baris yang sama beberapa kali, jadi tabel mendapat beberapa baris untuk satu variabel. Telusuri ini:

n := 4
result := 1
for i := 1; i <= n; i++ {
    result = result * i
}
fmt.Println(result)

Baris for punya tiga bagian yang dipisahkan titik koma: i := 1 berjalan sekali di awal, i <= n adalah pertanyaan yang diajukan sebelum setiap putaran, dan i++ menambah 1 ke i setelah setiap putaran. Jadi perulangan berjalan dengan i bernilai 1, lalu 2, 3, 4. Setiap kali, isi perulangan mengalikan result dengan i saat itu:

Putaran (i) result sebelum result sesudah
1 1 1
2 1 2
3 2 6
4 6 24

Setelah perulangan, result bernilai 24, jadi program mencetak 24. (Kamu baru saja menelusuri 1×2×3×4. Hasil itu punya nama, "4 faktorial", tetapi kamu tidak perlu tahu itu untuk menelusurinya.)

Menelusuri keputusan

Untuk if, kamu tidak mengisi tabel. Kamu mengikuti satu jalur yang pertanyaannya benar. Telusuri ini dengan score bernilai 72:

score := 72
if score >= 90 {
    fmt.Println("A")
} else if score >= 70 {
    fmt.Println("B")
} else {
    fmt.Println("C")
}

Baca dengan suara keras: apakah 72 setidaknya 90? Tidak, lewati. Apakah 72 setidaknya 70? Ya, cetak B, lewati sisanya. Outputnya B. Hanya cabang pertama yang benar yang berjalan; sisanya tidak pernah diperiksa.

Di atas kertas, ubah baris pertama contoh perulangan menjadi n := 5. Tambahkan satu baris lagi ke tabel penelusuran dan hitung nilai baru yang dicetak. (Kamu seharusnya mendapat angka lima kali lebih besar dari sebelumnya.)

Mengapa perlu menelusuri?

  • Menemukan bug sebelum program dijalankan. Sebagian besar bug adalah baris yang melakukan sesuatu yang sedikit berbeda dari bayanganmu. Menelusuri memaksamu membaca apa yang sebenarnya dikatakan setiap baris.
  • Membaca kode orang lain. Nanti kamu akan menempelkan contoh Go dari internet. Menelusuri adalah cara kamu memahaminya, bukan sekadar berharap kodenya benar.
  • Membuatmu melambat di tempat yang penting. Mengisi tabel penelusuran itu membosankan, dan memang itu tujuannya: kebosanan itu menahanmu agar tidak melewati baris yang sulit.

PR

Kertas lagi. Tanpa komputer. Untuk setiap soal, buat tabel penelusuran (atau ikuti cabangnya) dan tuliskan output akhirnya. Periksa jawabanmu hanya setelah kamu memutuskan jawaban, dan setelah sampai di bab yang memungkinkan kamu menjalankan kode.

Soal 1 — Jumlah hitungan mundur

Telusuri program ini dan tuliskan nilai yang dicetak.

s := 0
for i := 5; i > 0; i-- {
    s = s + i
}
fmt.Println(s)

(Petunjuk: perulangan ini menghitung mundur. i-- mengurangi i sebanyak 1 setelah setiap putaran, jadi i bernilai 5, lalu 4, 3, 2, 1.)

Soal 2 — Membangun string

Telusuri ini dan tuliskan persis apa yang dicetak.

word := "ha"
out := ""
for i := 0; i < 3; i++ {
    out = out + word
}
fmt.Println(out)

Tanda + menyambung dua potong teks. out awalnya kosong.

Soal 3 — Pertukaran

Telusuri ini dengan tabel untuk a, b, dan temp. Tuliskan baris output akhirnya.

a := 2
b := 7
temp := a
a = b
b = temp
fmt.Println(a, b)

Jelaskan dalam satu kalimat apa tugas variabel temp.

Tantangan — Temukan kejutannya

Telusuri ini dan tuliskan nilai yang dicetak. Kebanyakan orang salah menebak pada bacaan pertama, jadi pelan-pelan saja dan percayai tabelnya.

price := 100
discount := 20
final := price - discount
discount = 50
fmt.Println(final)

Lalu tulis satu kalimat yang menjelaskan apakah mengubah discount pada baris kedua dari terakhir memengaruhi final, dan mengapa.

Bingung atau sudah selesai? Buka halaman Solusi PR.