02. Program C++ pertama

Program C++ terpendek yang berguna berisi enam baris. Bab ini membedah keenamnya, lalu menambahkan komentar dan cara membaca pesan error pertama.

Bentuk dasar

#include <iostream>
using namespace std;

int main() {
    cout << "Halo, OSN!" << endl;
    return 0;
}

Compile dan jalankan:

g++ -std=c++17 -O2 -o halo exercises/02/01-halo.cpp
./halo

Keluaran:

Halo, OSN!

Sekarang baris per baris.

Baris Tugasnya
#include <iostream> memasukkan pustaka masukan/keluaran, sumber cout dan cin
using namespace std; membuat nama-nama pustaka standar bisa ditulis tanpa std::
int main() { awal fungsi main, tempat program mulai dijalankan
cout << "Halo, OSN!" << endl; mencetak teks lalu pindah baris
return 0; memberi tahu sistem bahwa program selesai tanpa masalah
} akhir fungsi main

Sekarang keenam baris itu dibedah lebih dalam, karena kerangka ini akan kamu ketik ratusan kali.

#include <iostream>. Tanda # menandai perintah untuk tahap prapengolahan di Bab 01: sebelum kode diterjemahkan, isi berkas iostream disalin ke tempat baris ini berada. Di dalamnya ada keterangan tentang cout dan cin. Tanpa baris ini, compiler tidak tahu cout itu apa dan menolak dengan 'cout' was not declared in this scope. Baris #include tidak diakhiri titik koma — ia bukan pernyataan C++, melainkan perintah untuk prapengolah.

using namespace std;. Pustaka standar menaruh semua namanya di dalam satu wadah nama bernama std, supaya tidak bentrok dengan nama buatanmu sendiri. Nama lengkap cout sebenarnya std::cout. Baris ini berkata "kalau ada nama yang tidak kukenal, cari juga di dalam std", sehingga std:: boleh dihilangkan.

int main(). Sistem operasi butuh satu titik masuk: satu fungsi yang dijalankan lebih dulu. Di C++ namanya selalu main. Kata int di depannya berarti main mengembalikan sebuah bilangan bulat kepada sistem operasi, dan kurung () adalah daftar parameternya — kosong, karena main di buku ini tidak menerima apa-apa.

Kurung kurawal { }. Sepasang kurung kurawal menandai satu blok: sekumpulan pernyataan yang dianggap satu kesatuan. Isi main adalah blok. Nanti if, for, dan fungsi lain juga memakai blok yang sama bentuknya. Setiap { wajib punya pasangan }.

return 0;. Angka yang dikembalikan main disebut kode keluar: 0 berarti "selesai tanpa masalah", nilai lain berarti ada yang salah. Penilai daring membaca angka ini — program yang berakhir dengan kode selain 0 dinilai Runtime Error walaupun keluarannya sudah benar.

Kerangka lima baris ini sama untuk hampir setiap soal OSN. Ketik ulang dari awal setiap kali berlatih, jangan disalin-tempel, sampai jari hafal. Peserta yang harus berpikir dulu untuk menulis kerangkanya kehilangan waktu di menit pertama lomba, saat pikiran justru masih paling segar.

Tiga hal yang perlu diingat sejak sekarang:

  • Setiap pernyataan diakhiri titik koma (;). Ini penyebab error paling sering bagi pemula.
  • main selalu ada. Program tanpa main tidak bisa di-compile.
  • Huruf besar-kecil dibedakan. Cout bukan cout, Main bukan main.

using namespace std; dipakai sepanjang buku ini karena memperpendek kode, dan di lomba pemrograman kode yang pendek lebih cepat ditulis. Di proyek perangkat lunak besar, banyak orang memilih menulis std::cout secara lengkap. Keduanya benar.

Mencetak dengan cout

cout adalah "aliran keluaran". Tanda << mendorong nilai ke aliran itu. Beberapa nilai bisa didorong dalam satu pernyataan:

int nilai = 90;
cout << "Nilai: " << nilai << endl;

Keluaran:

Nilai: 90

endl memindahkan kursor ke baris baru. Alternatifnya adalah menulis "\n" di dalam teks:

cout << "baris satu\n";
cout << "baris dua\n";

Perbedaannya: endl juga memaksa keluaran langsung ditulis (flush), sedangkan "\n" tidak. Untuk soal dengan keluaran sangat banyak, "\n" lebih cepat. Buku ini memakai "\n" mulai Bagian 3.

Tanpa endl atau "\n", keluaran menempel jadi satu baris:

cout << "Halo";
cout << "OSN";
HaloOSN

Teks dan nilai adalah dua hal berbeda

Apa pun yang berada di dalam tanda kutip ganda dicetak apa adanya. Apa pun yang berada di luarnya dihitung dulu, baru dicetak:

cout << "1 + 2" << "\n";     // teks
cout << 1 + 2 << "\n";       // perhitungan
1 + 2
3

Kesalahan sebaliknya juga sering terjadi: nilai yang dicetak berdempetan karena tidak ada spasi yang ikut dicetak. Spasi di antara << tidak ikut tercetak — spasi harus ditulis sebagai teks:

int a = 3, b = 4;
cout << a << b << "\n";        // 34
cout << a << " " << b << "\n"; // 3 4

Buka exercises/02/02-baris-dan-spasi.cpp. Hapus satu endl, compile ulang, dan lihat bagaimana dua baris menempel menjadi satu.

Karakter khusus

Beberapa karakter tidak bisa ditulis langsung di dalam tanda kutip. Untuk itu ada escape, yaitu garis miring terbalik diikuti satu huruf:

Tulis Hasil di layar
\n pindah baris
\t satu tab
\" tanda kutip ganda
\\ satu garis miring terbalik
cout << "Dia berkata \"siap\"\n";
cout << "Nama:\tBudi\n";
cout << "Folder: C:\\osn\n";
Dia berkata "siap"
Nama:   Budi
Folder: C:\osn

Komentar

Komentar adalah catatan untuk manusia; compiler melewatinya.

// komentar satu baris

/* komentar
   beberapa baris */

Di lomba, komentar dipakai untuk mencatat ide penyelesaian, bukan menerjemahkan kode baris per baris. Bandingkan:

// menambahkan 1 ke i         <- tidak berguna
i++;

// sisa pembagian dipakai supaya nilai tetap di bawah 1e9+7
hasil %= MOD;

Buka exercises/02/03-komentar.cpp. Ubah satu baris kode menjadi komentar dengan menambahkan // di depannya, compile ulang, lalu perhatikan baris mana yang hilang dari keluaran.

Membaca pesan error

Compiler menolak kode yang salah tulis, lalu mencetak pesan. Pesan itu panjang, tetapi bagian yang penting selalu ada di awal: nama file, nomor baris, nomor kolom, dan keterangan.

Contoh kode salah:

#include <iostream>
using namespace std;

int main() {
    cout << "Halo" << endl
    return 0;
}

Pesannya kira-kira:

error.cpp: In function 'int main()':
error.cpp:5:28: error: expected ';' before 'return'
    5 |     cout << "Halo" << endl
      |                            ^
      |                            ;
    6 |     return 0;
      |     ~~~~~~

Cara membacanya:

  1. error.cpp:5:28 — file error.cpp, baris 5, kolom 28.
  2. expected ';' before 'return' — compiler ingin titik koma sebelum return.
  3. Tanda ^ menunjuk posisinya.

Perhatikan: kesalahannya di baris 5, tetapi compiler baru sadar ketika sampai baris 6. Jadi kalau baris yang ditunjuk terlihat benar, periksa baris di atasnya.

Tiga pesan yang akan sering kamu temui:

Pesan Artinya
expected ';' before ... ada titik koma yang hilang
'x' was not declared in this scope variabel dipakai sebelum dibuat, atau salah eja
expected '}' at end of input ada kurung kurawal penutup yang kurang

Compiler bisa mencetak puluhan baris error dari satu kesalahan. Selalu perbaiki error paling atas dulu, lalu compile lagi. Sering kali sisanya ikut hilang.

Contoh kedua, salah huruf besar-kecil:

int nilai = 90;
cout << Nilai << "\n";
salah.cpp: In function 'int main()':
salah.cpp:6:13: error: 'Nilai' was not declared in this scope; did you mean 'nilai'?
    6 |     cout << Nilai << "\n";
      |             ^~~~~
      |             nilai

Compiler bahkan menebak maksudmu di baris terakhir: did you mean 'nilai'. Pesan was not declared in this scope hampir selalu berarti salah satu dari tiga hal — salah eja, salah huruf besar-kecil, atau variabelnya memang belum dibuat.

Contoh ketiga, kurung kurawal penutup yang hilang:

salah2.cpp: In function 'int main()':
salah2.cpp:6:14: error: expected '}' at end of input
    6 |     return 0;
      |              ^
salah2.cpp:4:12: note: to match this '{'
    4 | int main() {
      |            ^

Perhatikan baris note: di bawahnya: compiler menunjukkan { mana yang belum punya pasangan. Baris note: sering lebih berguna daripada baris error: itu sendiri, jadi jangan berhenti membaca di baris pertama.

Kebiasaan yang mempercepat semuanya: compile setiap selesai menulis lima sampai sepuluh baris, jangan menunggu seluruh program jadi. Satu kesalahan di antara sepuluh baris baru mudah ditemukan; tiga kesalahan di antara delapan puluh baris saling menutupi dan menghasilkan pesan yang membingungkan.

Kesalahan yang paling sering

Yang tertulis Akibatnya
titik koma hilang expected ';' before ... di baris berikutnya
Cout, Main, Int was not declared in this scope
#include <iostream>; titik koma tidak perlu pada baris #include
kutip pembuka tanpa kutip penutup missing terminating " character
{ tanpa } expected '}' at end of input
cout << Halo; (tanpa tanda kutip) dianggap nama variabel, bukan teks
cout >> x; arah tanda salah; cout memakai <<

Tips OSN

Keluaran dibandingkan karakter per karakter. Mesin penilai tidak membaca maksudmu; ia membandingkan berkas keluaranmu dengan berkas jawaban. Karena itu tiga hal berikut sama-sama berakibat Wrong Answer: huruf besar-kecil yang berbeda, spasi yang kurang atau berlebih, dan baris baru yang hilang. Banyak penilai memaafkan spasi di ujung baris, tetapi tidak semua — jangan bergantung pada kemurahan hati mesin.

Jangan pernah mencetak kalimat pengantar. Program lomba tidak berbicara dengan manusia. cout << "Masukkan angka: "; adalah kesalahan yang paling sering membuat jawaban benar ditolak, karena kalimat itu ikut masuk ke berkas keluaran.

Periksa keluaranmu dengan mata mesin. Di terminal Linux, ./program | cat -A menampilkan tab sebagai ^I dan akhir baris sebagai $, sehingga spasi tersembunyi kelihatan. Cara yang lebih baik lagi: simpan keluaran yang diharapkan ke berkas, lalu bandingkan otomatis.

./program > keluaran-saya.txt
diff keluaran-saya.txt keluaran-benar.txt

Kalau diff tidak mencetak apa-apa, kedua berkas identik. Ini kebiasaan yang menghemat banyak waktu dibandingkan membandingkan dengan mata.

Satu berkas, satu soal. Setiap soal dikirim sebagai satu berkas .cpp yang berdiri sendiri. Tidak ada berkas pendukung, tidak ada folder, tidak ada baca-tulis berkas. Program yang membuka berkas dengan nama tetap akan gagal di mesin penilai.

return 0; bukan hiasan. Kode keluar selain 0 dinilai Runtime Error, walaupun seluruh keluarannya sudah benar. Di C++17 main boleh tidak menulis return 0; — compiler menambahkannya sendiri — tetapi menulisnya tetap kebiasaan yang baik, karena membuat titik akhir program terlihat.

endl memaksa keluaran ditulis ke sistem setiap kali dipanggil. Untuk soal yang mencetak ratusan ribu baris, kebiasaan memakai endl bisa membuat program yang seharusnya cepat menjadi Time Limit Exceeded. Biasakan "\n"; pakai endl hanya kalau memang perlu memaksa flush.

Ringkasan

  • Kerangka wajib setiap program: #include <iostream>, using namespace std;, int main() { ... return 0; }.
  • cout << nilai; mencetak; << boleh dirangkai berkali-kali dalam satu pernyataan.
  • Di dalam tanda kutip dicetak apa adanya, di luar tanda kutip dihitung dulu.
  • "\n" dan endl sama-sama memindahkan baris; "\n" lebih cepat untuk keluaran yang banyak.
  • Escape yang perlu dihafal: \n, \t, \", \\.
  • Baca pesan error dari atas, perhatikan nomor baris dan kolomnya, dan periksa juga baris di atas baris yang ditunjuk.

Pekerjaan rumah

Soal 1 — Biodata

Buka exercises/02/homework/01-biodata.cpp. Cetak empat baris: nama, kelas, asal sekolah, dan satu kalimat alasan ingin ikut OSN. Pakai satu pernyataan cout untuk setiap baris.

Soal 2 — Kartu nama

Buka exercises/02/homework/02-kartu-nama.cpp. Cetak kotak dari karakter +, -, dan | dengan namamu di tengah, misalnya:

+----------------+
|   Budi Santoso |
+----------------+

Belum boleh memakai perulangan — tulis barisnya satu per satu.

Soal 3 — Tabel dengan tab

Buka exercises/02/homework/03-tabel-tab.cpp. Cetak tabel tiga baris berisi nama dan nilai tiga teman, dipisahkan \t sehingga kolomnya rapi.

Soal 4 — Perbaiki error

Buka exercises/02/homework/04-perbaiki-error.cpp. File ini sengaja dibuat gagal compile dan berisi tiga kesalahan. Compile, baca pesan pertama, perbaiki satu kesalahan, compile lagi — sampai program berjalan dan mencetak Semua error sudah diperbaiki.

Tantangan — Kutipan berlapis

Buka exercises/02/homework/05-kutipan.cpp. Cetak persis baris berikut, termasuk tanda kutip dan garis miringnya:

Guru berkata: "tulis \n untuk pindah baris"

Latihan bergaya OSN

Tiga soal berikut ditulis dalam format yang dipakai di OSN: deskripsi, format masukan, format keluaran, batasan, lalu contoh. Ketiganya belum memakai masukan — pembacaan masukan baru dibahas di Bab 03 — tetapi cara mengerjakannya sudah sama persis dengan soal sungguhan: kerjakan di satu berkas .cpp, jalankan, lalu bandingkan keluarannya dengan contoh sampai sama karakter per karakter.

Kerangka ketiganya ada di exercises/02/osn/.

Soal 1 — Papan Catur

Panitia OSN mencetak papan catur berukuran 8 × 8 untuk lomba antarbabak. Kotak hitam digambar sebagai # dan kotak putih sebagai .. Kotak di pojok kiri atas berwarna hitam, dan warna kotak berselang-seling ke kanan maupun ke bawah.

Format masukan. Tidak ada masukan.

Format keluaran. Delapan baris, masing-masing berisi delapan karakter # atau ..

Batasan. Ukuran papan tetap 8 × 8. Belum boleh memakai perulangan.

Contoh keluaran

#.#.#.#.
.#.#.#.#
#.#.#.#.
.#.#.#.#
#.#.#.#.
.#.#.#.#
#.#.#.#.
.#.#.#.#

Penjelasan. Hanya ada dua bentuk baris, dan keduanya berselang-seling. Menulis delapan baris cout sudah cukup; yang diuji di sini adalah ketelitian, bukan teknik.

Kerangkanya: exercises/02/osn/01-papan-catur.cpp

Soal 2 — Tangga

Gambarkan tangga lima anak yang rata kanan. Baris pertama berisi satu tanda #, baris kedua dua tanda #, dan seterusnya sampai baris kelima berisi lima tanda #. Setiap baris lebarnya tepat lima kolom, sehingga tanda # selalu berakhir di kolom kelima.

Format masukan. Tidak ada masukan.

Format keluaran. Lima baris. Baris ke-i berisi 5 - i spasi diikuti i tanda #. Tidak boleh ada spasi tambahan di akhir baris.

Batasan. Tinggi tangga tetap 5.

Contoh keluaran

    #
   ##
  ###
 ####
#####

Penjelasan. Baris pertama berisi empat spasi lalu satu #, jadi panjangnya lima karakter. Perhatikan larangan spasi di akhir baris: tangga rata kanan tidak memerlukannya, tetapi tangga rata kiri yang "dirapikan" dengan spasi di belakang akan ditolak.

Kerangkanya: exercises/02/osn/02-tangga.cpp

Soal 3 — Struk Toko

Sebuah kasir mencetak struk berisi nama toko, lokasi berkas catatannya, dan dua baris barang. Nama toko diapit tanda kutip ganda, dan lokasi berkas ditulis dengan pemisah folder gaya Windows. Antar kolom dipisahkan satu karakter tab.

Format masukan. Tidak ada masukan.

Format keluaran. Empat baris:

  1. kata Toko, tab, lalu "Sumber Rejeki" beserta tanda kutipnya;
  2. kata Berkas, tab, lalu C:\struk\2026.txt;
  3. kata Pensil, tab, 3, tab, 6000;
  4. kata Buku, tab, 2, tab, 14000.

Batasan. Pemisah kolom harus satu karakter tab, bukan beberapa spasi.

Contoh keluaran

Toko    "Sumber Rejeki"
Berkas  C:\struk\2026.txt
Pensil  3   6000
Buku    2   14000

Penjelasan. Tanda kutip ganda di dalam teks ditulis \", satu garis miring terbalik ditulis \\, dan tab ditulis \t. Di layar, tab terlihat seperti beberapa spasi — tetapi bagi mesin penilai keduanya berbeda, dan mengganti tab dengan spasi akan dinilai salah.

Kerangkanya: exercises/02/osn/03-struk.cpp

Bingung atau sudah selesai? Buka halaman pembahasan PR.