Setelah mengetahui siapa yang menerjemahkan C++ dan bagaimana tahapan kompilasinya, sekarang kita membongkar benda yang diterjemahkan itu sendiri: file .cpp. Program C++ sekecil apa pun selalu tersusun dari blok-blok yang sama — directive preprocessor, deklarasi, definisi fungsi, dan fungsi main() sebagai pintu masuk eksekusi. Memahami anatomi ini membuat setiap program baru terasa familiar, bukan sekadar kumpulan simbol yang dihafal. Pada Chapter ini kita bedah satu program lengkap baris demi baris, membandingkan directive preprocessor dengan statement, menguji perilaku main() tanpa return 0, dan menutup dengan program yang menerima argumen dari baris perintah.

Anatomi File .cpp #

File .cpp adalah source code: teks biasa yang berisi instruksi untuk compiler. Susunannya secara umum berlapis dari atas ke bawah: directive preprocessor di bagian paling atas, diikuti konstanta dan deklarasi global, lalu definisi fungsi, dan di antaranya selalu ada satu fungsi istimewa bernama main(). Ketika sistem operasi menjalankan program, runtime library C++ memanggil main() dan eksekusi dimulai dari baris pertamanya. Compiler membaca file dari atas ke bawah, sehingga sebuah nama — misalnya konstanta atau fungsi — harus diketahui terlebih dahulu sebelum dipakai; inilah alasan definisi biasanya diletakkan di atas main().

Contoh Program Lengkap dan Bedah Barisnya #

Program berikut menghitung luas lingkaran. Ukurannya kecil, tetapi memuat semua lapisan anatomi: directive, konstanta global, fungsi biasa, dan main() dengan statement serta status kembalian.

cpp
#include <iostream>  // directive preprocessor: menyertakan header iostream

const double PI = 3.14159;  // konstanta global yang dipakai fungsi di bawahnya

// Fungsi biasa: menghitung luas lingkaran dari jari-jarinya.
double luasLingkaran(double jariJari) {
    return PI * jariJari * jariJari;
}

int main() {  // titik awal eksekusi setiap program C++
    double jariJari = 7.0;
    std::cout << "Jari-jari : " << jariJari << "\n";
    std::cout << "Luas      : " << luasLingkaran(jariJari) << "\n";
    return 0;  // status selesai: 0 berarti program sukses
}

Output yang Dihasilkan:

text
Jari-jari : 7
Luas      : 153.938

Mari kita bedah satu per satu:

  1. Baris 1 (#include <iostream>): directive preprocessor — bukan statement. Preprocessor menyisipkan isi header iostream sehingga std::cout dikenal compiler; mekanisme lengkapnya dibahas pada Chapter Header dan Include.
  2. Baris 3 (const double PI): konstanta global bertipe double berskala const. Karena dideklarasikan sebelum luasLingkaran, fungsi di bawahnya boleh memakainya.
  3. Baris 6-8 (fungsi luasLingkaran): fungsi biasa dengan satu parameter double. Nilai PI * jariJari * jariJari dihitung terlebih dahulu, lalu dikembalikan ke pemanggil.
  4. Baris 10 (int main()): titik masuk program. Tipe kembaliannya int karena fungsi ini wajib melaporkan status akhir eksekusi kepada sistem operasi.
  5. Baris 11-13 (statement): tiga statement — deklarasi variabel jariJari, lalu dua perintah output. Setiap statement diakhiri titik koma dan dikerjakan berurutan, satu per baris.
  6. Baris 14 (return 0): program melaporkan selesai tanpa kesalahan; nilai kembaliannya diteruskan ke sistem operasi sebagai exit code.

Perhatikan juga komentar yang diawali // pada setiap lapisan — compiler mengabaikan seluruh isinya, tetapi komentar menyelamatkan pembaca program di masa depan, termasuk diri kita sendiri.

Preprocessor Directive vs Statement #

Dua jenis baris di program tadi bekerja pada waktu yang berbeda dan sering tertukar oleh pemula. Tabel berikut merangkum perbedaannya:

AspekDirective preprocessorStatement
PenandaDiawali # di awal barisBaris kode biasa, diakhiri ;
Waktu diprosesSebelum kompilasi, berupa manipulasi teksSaat program berjalan, oleh CPU
Diakhiri titik komaTidakWajib
Contoh#include <iostream>std::cout << "Halo\n";
HasilnyaTeks sumber baru untuk compilerMachine code dalam executable

Directive memodifikasi teks sumber sebelum compiler melihatnya — menyisipkan header, mengganti makro, atau memilih blok kode yang ikut dikompilasi. Statement adalah instruksi yang benar-benar dieksekusi ketika program berjalan. Perbedaan waktu inilah yang menjelaskan perilaku #ifdef pada program cek fitur di Chapter Standar Bahasa C++: blok yang tidak terpilih tidak pernah sampai ke compiler.

Return 0: Status Akhir Program #

Nilai kembalian main() menjadi exit code program — angka yang bisa dibaca sistem operasi dan alat lain untuk menilai hasil eksekusi. Konvensinya: 0 berarti sukses, nilai selain nol berarti terjadi masalah; header <cstdlib> menyediakan konstanta EXIT_SUCCESS dan EXIT_FAILURE yang maknanya sama. Di terminal Linux, nilai ini muncul di variabel shell $?, dan tools seperti script CI atau build system mengandalkannya untuk memutuskan apakah sebuah langkah berhasil. Program kita sejauh ini selalu mengembalikan 0 secara eksplisit, dan kebiasaan menulisnya secara gamblang adalah latihan yang baik.

Bolehkah main() Tanpa return? #

Boleh — dan ini aturan khusus yang hanya berlaku untuk main(). Standar C++ menetapkan: bila eksekusi mencapai akhir main() tanpa menemui return, compiler wajib menyisipkan return 0 secara implisit. Program berikut memang sengaja tidak menulisnya:

cpp
#include <iostream>

int main() {
    std::cout << "Fungsi main ini tidak punya return eksplisit.\n";
    std::cout << "Compiler tetap menyisipkan return 0 secara implisit.\n";
}

Output yang Dihasilkan:

text
Fungsi main ini tidak punya return eksplisit.
Compiler tetap menyisipkan return 0 secara implisit.

Kompilasi program di atas dengan g++ -std=c++23 -Wall -Wextra tidak menghasilkan warning, dan bila kita periksa $? setelah menjalankannya, nilainya 0 — bukti return 0 implisit bekerja. Referensi resmi aturan ini ada di halaman main function cppreference .

Argumen dari Baris Perintah #

main() punya bentuk kedua yang menerima data dari luar: int main(int argc, char* argv[]). Parameter argc (argument count) berisi jumlah argumen, dan argv (argument vector) adalah array berisi argumen tersebut sebagai teks — argv[0] berisi nama program itu sendiri, sehingga argumen dari pengguna mulai di indeks 1. Bentuk ini dipakai ketika program butuh input sebelum berjalan, misalnya nama file atau opsi seperti -h. Program kecil berikut menampilkannya:

cpp
#include <iostream>

int main(int argc, char* argv[]) {
    std::cout << "Jumlah argumen: " << argc << "\n";

    // argv[0] berisi nama/path program, jadi argumen pengguna mulai dari
    // indeks 1.
    for (int i = 1; i < argc; ++i) {
        std::cout << "Argumen ke-" << i << ": " << argv[i] << "\n";
    }

    return 0;
}

Output yang Dihasilkan:

text
Jumlah argumen: 3
Argumen ke-1: Dewi
Argumen ke-2: 27

Program dijalankan dengan dua argumen, Dewi dan 27, sehingga argc bernilai 3 — dua argumen pengguna ditambah satu untuk nama program. Loop for pada baris 10 mengunjungi indeks mulai dari 1 agar nama program tidak ikut dicetak. Perhatikan bahwa semua argumen masuk sebagai teks; mengubah "27" menjadi angka 27 memerlukan konversi eksplisit, topik yang akan kita gali pada Chapter Input dengan cin. Cara menjalankan program beserta argumennya dibahas pada Chapter Menjalankan Program di Section Persiapan Lingkungan.

Dengan Chapter ini, anatomi program C++ sudah terbongkar utuh: directive di atas, konstanta dan fungsi di tengah, main() sebagai pintu masuk, serta exit code sebagai laporan akhirnya. Fondasi konseptual Section Pengenalan C++ selesai; pada Section berikutnya kita mulai berpraktik sungguhan — memilih compiler, memasangnya, dan mengompilasi program pertama secara lengkap dari terminal kita sendiri.