Hampir semua file .cpp yang kita tulis dibuka dengan beberapa baris #include. Perintah ini adalah cara kita memberi tahu compiler tentang alat yang tersedia di luar file: fungsi mencetak, tipe string, fungsi matematika, dan banyak lagi. C++ sendiri hanya mengenal sedikit fungsi bawaan; sisanya hidup di pustaka standar yang harus kita “unduh” lewat header. Pada Chapter ini kita mempelajari apa itu header file, perbedaan dua gaya penulisan #include, header standar yang paling sering dipakai, dan apa sebenarnya yang terjadi di balik layar saat perintah itu dieksekusi.

Apa Itu Header File #

Header file adalah file teks berisi deklarasi: daftar nama fitur yang tersedia beserta bentuknya, tanpa selalu menyertakan implementasinya. Analoginya seperti daftar isi pustaka — kita membaca daftar itu untuk tahu fungsi apa saja yang bisa dipinjam. Ketika kita menulis std::cout, compiler tidak langsung tahu apa itu std::cout; ia perlu deklarasi yang ada di header <iostream>. Tanpa deklarasi tersebut, compiler menghentikan kompilasi dengan pesan 'cout' was not declared in this scope. Deklarasi di header dipisahkan dari implementasi agar compiler cukup membaca antarmuka saja, sedangkan kode implementasinya sudah dikompilasi sebelumnya di pustaka sistem.

Dua Gaya Penulisan Include: Sudut dan Kutip #

Ada dua bentuk penulisan #include yang tampak mirip tetapi punya aturan pencarian berbeda:

BentukContohDipakai untukLokasi pencarian
Sudut < >#include <iostream>Header pustaka standar dan pustaka eksternalFolder header sistem (mis. /usr/include)
Kutip " "#include "sapaan.h"Header milik proyek kita sendiriFolder file yang meng-include, lalu folder header sistem

Bentuk kutip biasanya dicari lebih dulu di direktori tempat file sumber berada, sehingga cocok untuk header lokal proyek. Bentuk sudut langsung menuju direktori include sistem. Mencampur keduanya (misalnya #include <sapaan.h> untuk header sendiri) sering gagal karena file kita tidak ada di folder sistem. Kebiasaan yang sehat: < > untuk semua yang berasal dari luar proyek, " " untuk file buatan sendiri.

Header Standar yang Sering Kita Pakai #

Pustaka standar C++ terbagi menjadi puluhan header, dan daftar resminya bisa dijelajahi di halaman header library cppreference. Untuk tahap awal belajar, empat header ini yang akan paling sering muncul di kode kita:

HeaderIsi utamaContoh yang digunakan
<iostream>Stream input-outputstd::cout, std::cin, std::cerr
<string>Tipe teks std::stringstd::string nama = "Budi";
<vector>Array dinamis std::vectorstd::vector<int> nilai;
<cmath>Fungsi matematikastd::sqrt, std::pow

Program berikut memakai keempatnya sekaligus agar kita terbiasa melihat pola penulisannya:

cpp
#include <cmath>     // std::sqrt, std::pow
#include <iostream>  // std::cout
#include <string>    // std::string
#include <vector>    // std::vector

int main() {
    double akar = std::sqrt(144.0);
    double pangkat = std::pow(2.0, 10.0);

    std::string sapaan = "Halo";
    std::vector<int> nilai;
    nilai.push_back(90);
    nilai.push_back(85);

    std::cout << sapaan << ", akar 144 = " << akar << "\n";
    std::cout << "2 pangkat 10 = " << pangkat << "\n";
    std::cout << "Jumlah nilai tersimpan: " << nilai.size() << "\n";
    std::cout << "Nilai pertama: " << nilai.front() << "\n";

    return 0;
}

Output yang Dihasilkan:

text
Halo, akar 144 = 12
2 pangkat 10 = 1024
Jumlah nilai tersimpan: 2
Nilai pertama: 90

Perhatikan urutan #include di atas disusun alfabetis dengan komentar fungsinya — bukan keharusan, tetapi kebiasaan yang membuat file mudah dipindai. Nama-nama baru seperti std::vector dan metode push_back sengaja kita pakai seperlunya saja; masing-masing dibedakan tuntas pada Section Variabel dan Tipe Data dan Section selanjutnya.

Apa yang Terjadi Saat Kompilasi #

Perintah #include bukan bagian dari C++ yang dieksekusi program, melainkan arahan bagi preprocessor — tahap yang berjalan sebelum kompilasi sesungguhnya. Preprocessor bekerja sangat sederhana namun radikal: ia menyalin seluruh isi file header, kata demi kata, ke posisi baris #include yang memanggilnya. Hasil penyisipan inilah yang disebut translation unit, yaitu satu berkas gabungan yang benar-benar dikompilasi menjadi object file.

Karena prosesnya menyalin teks, header besar yang di-include banyak file akan diproses berulang kali — itulah alasan waktu kompilasi C++ terasa lebih lama dibanding bahasa yang punya sistem modul. Standar C++23 memiliki fitur modules (import std;), tetapi dukungan compiler-nya masih bertahap sehingga #include tetap gaya yang kita pakai sehari-hari. Lebih dalam tentang tahapan build dibedah pada Section Build System dan Project Structure.

Header Lokal Milik Proyek #

Kita juga bisa membuat header sendiri. Buat file sapaan.h di folder yang sama dengan kode utama:

cpp
#ifndef SAPAAN_H
#define SAPAAN_H

// Header lokal: menyimpan data yang bisa dipakai banyak file.
const char* SAMBUTAN = "Halo dari header lokal!";

#endif

lalu panggil dengan bentuk kutip:

cpp
#include <iostream>
#include "sapaan.h"   // header lokal: dicari mulai dari folder ini

int main() {
    std::cout << SAMBUTAN << "\n";

    return 0;
}

Output yang Dihasilkan:

text
Halo dari header lokal!

Preprocessor menyisipkan isi sapaan.h tepat di baris #include "sapaan.h", sehingga nama SAMBUTAN dikenal sebelum dipakai di main(). Konstanta SAMBUTAN sendiri bertipe const char* — string gaya C yang akan kita perbandingkan dengan std::string nanti.

Header Guards: Mencegah Penyisipan Ganda #

Jika satu header di-include dua kali dalam satu translation unit (misalnya lewat dua header berbeda), isi yang sama tersalin dua kali dan compiler protes karena nama dideklarasikan ulang. Solusi standarnya adalah header guard: tiga baris preprocessor yang membungkus seluruh isi header, persis seperti pada sapaan.h di atas.

cpp
#ifndef SAPAAN_H      // jika SAPAAN_H belum didefinisikan...
#define SAPAAN_H      // ...definisikan sekarang

// isi header ditulis di sini

#endif                // akhir wilayah guard

Pembacaan logikanya: saat pertama disisipkan, makro SAPAAN_H belum ada sehingga isi header ikut; saat disisipkan lagi di file yang sama, makro sudah terdefinisi sehingga seluruh isi dilewati. Banyak compiler juga menerima #pragma once yang lebih ringkas, meskipun bukan bagian resmi standar. Untuk saat ini cukup hafalkan polanya; implementasi lengkap dengan beberapa file dibahas pada Section Build System dan Project Structure.

Dengan header, kita sudah tahu cara membawa nama-nama pustaka ke dalam program. Pertanyaan berikutnya muncul begitu pustaka tumbuh besar: bagaimana mencegah dua pustaka memakai nama yang sama? Di sinilah namespace berperan, dan itulah topik Chapter berikutnya.