Kita sebenarnya sudah menulis return sejak program pertama — return 0; di ujung setiap main() — tanpa pernah membahasnya sungguh-sungguh. Sekarang saatnya: return adalah pernyataan yang mengakhiri eksekusi sebuah fungsi SEGERA dan, bila fungsinya menjanjikan nilai kembalian, menyerahkan nilai itu kepada pemanggil. Pada main() khususnya, nilai kembaliannya diserahkan ke sistem operasi sebagai exit code — bukti tertulis apakah program berakhir sukses atau bermasalah. Pada Chapter ini kita membaca exit code dari luar, memakai return sebagai alat kendali alur di dalam loop, dan mengenal return tanpa nilai pada fungsi void.

Exit Code: Pesan Akhir kepada Sistem Operasi #

Saat program berakhir, sistem operasi menerima satu angka dari main(): konvensinya 0 berarti sukses, dan angka lain (umumnya 1 sampai 255) adalah kode galat yang maknanya kita tetapkan sendiri. Angka inilah yang dibaca script shell, build tool, dan sistem otomatisasi untuk memutuskan langkah berikutnya. Program berikut memakai tiga jalur keluar dengan tiga kode berbeda:

cpp
#include <iostream>
#include <cstdlib>

int main(int argc, char* argv[]) {
    if (argc < 3) {
        std::cout << "Pemakaian: bagi <angka1> <angka2>\n";
        return 1;   // exit code 1: pemakaian salah
    }

    int a = std::atoi(argv[1]);
    int b = std::atoi(argv[2]);

    if (b == 0) {
        std::cout << "Galat: pembagi tidak boleh nol\n";
        return 2;   // exit code 2: input tidak valid
    }

    std::cout << a << " / " << b << " = " << a / b << "\n";
    return 0;   // sukses
}

Output yang Dihasilkan:

text
10 / 2 = 5

Dengan argumen 10 2, kedua pemeriksaan lolos, pembagian tercetak, dan program berakhir lewat return 0. Sekarang jalankan program yang sama dengan pembagi nol — jalur kedua yang menarik:

cpp
#include <iostream>
#include <cstdlib>

int main(int argc, char* argv[]) {
    if (argc < 3) {
        std::cout << "Pemakaian: bagi <angka1> <angka2>\n";
        return 1;   // exit code 1: pemakaian salah
    }

    int a = std::atoi(argv[1]);
    int b = std::atoi(argv[2]);

    if (b == 0) {
        std::cout << "Galat: pembagi tidak boleh nol\n";
        return 2;   // exit code 2: input tidak valid
    }

    std::cout << a << " / " << b << " = " << a / b << "\n";
    return 0;   // sukses
}

Output yang Dihasilkan:

text
Galat: pembagi tidak boleh nol

Program berakhir dengan exit code 2, bukan 0 — dan angka itu bisa dibaca dari terminal. Di shell, variabel khusus $? menyimpan exit code perintah terakhir:

bash
./bagi 10 0
echo $?

Output yang Dihasilkan:

text
Galat: pembagi tidak boleh nol
2

Inilah kontrak senyap antara program kita dan ekosistem di sekitarnya: main() mengembalikan 0 untuk sukses, 1 bila pemakaian salah, 2 bila input tidak valid. Script pemanggil cukup menguji $? untuk mengetahui mana yang terjadi tanpa harus membaca teks outputnya. Rincian return di cppreference . Catatan baris demi baris: Baris 7-10 menolak pemanggilan tanpa cukup argumen — argc dan argv yang menyuplai datanya sudah kita kenal pada Chapter Fungsi main(); Baris 13-16 menolak pembagi nol; dan Baris 19-21 adalah jalur sukses yang hanya tercapai bila semua pemeriksaan lolos.

Early Return: Keluar Begitu Jawaban Ketemu #

return tidak harus menunggu baris terakhir. Pola early return mengakhiri fungsi begitu hasilnya sudah pasti — dan karena return mengakhiri SELURUH fungsi, ia sekaligus memutus loop yang sedang berjalan di dalamnya. Fungsi kecil berikut (detail fungsi menyusul tuntas di Section Fungsi; untuk sekarang cukup baca strukturnya) mencari akar kuadrat bulat dengan mencoba kandidat satu per satu:

cpp
#include <iostream>

// Fungsi kecil: detail fungsi dibahas pada Section Fungsi
int cariAkarKuadrat(int target) {
    for (int i = 1; i <= 20; ++i) {
        if (i * i == target) {
            return i;   // ketemu: keluar dari loop DAN fungsi sekaligus
        }
    }
    return -1;   // tidak ketemu setelah 20 kandidat diperiksa
}

int main() {
    std::cout << "Akar dari 144: " << cariAkarKuadrat(144) << "\n";
    std::cout << "Akar dari 50: " << cariAkarKuadrat(50) << "\n";
    return 0;
}

Output yang Dihasilkan:

text
Akar dari 144: 12
Akar dari 50: -1

Dua pemanggilan, dua akhir yang berbeda. Untuk target 144, loop menemukan 12 * 12 == 144 pada putaran ke-12 dan return i langsung mengakhiri fungsi — putaran 13 sampai 20 dibatalkan, dan nilai 12 melompat menempati posisi pemanggilan di dalam cout. Untuk target 50, tidak ada kandidat yang lolos uji, loop habis dengan wajar, dan fungsi berakhir lewat return -1 — kode penanda “tidak ketemu” yang lazim di kode C++. Bandingkan dengan break pada Chapter sebelumnya: break hanya keluar dari loop dan program harus menentukan langkah sesudahnya, sedangkan return menyelesaikan seluruh fungsi dalam satu langkah.

return pada Fungsi void #

Fungsi bertipe void tidak menjanjikan nilai apa pun, tetapi return; tanpa nilai tetap berguna: ia mengakhiri fungsi lebih awal tanpa memberikan hasil. Contoh berikut mempersingkat sapaan bila nama kosong:

cpp
#include <iostream>
#include <string>

// Fungsi void: mengembalikan tidak ada nilai; return hanya mengakhiri
void salam(std::string nama) {
    if (nama.empty()) {
        std::cout << "Halo, boleh kenalan?\n";
        return;   // keluar dari fungsi tanpa nilai
    }
    std::cout << "Halo, " << nama << "!\n";
}

int main() {
    salam("");
    salam("Siti");
    return 0;
}

Output yang Dihasilkan:

text
Halo, boleh kenalan?
Halo, Siti!

Pemanggilan pertama mengirim string kosong, memicu cabang if, dan return; mengakhiri salam sebelum baris sapaan tercapai. Pemanggilan kedua melewati if dengan aman dan menyambung ke sapaan lengkap. Perhatikan bahwa tanpa return;, cabang if tidak menghentikan apa pun — baris “Halo, !” akan tercetak setelah pesan kenalan. Alternatifnya adalah if-else, dan untuk kasus dua cabang keduanya setara; early return mulai bersinar bila cabang penolakan ada banyak, karena setiap pemeriksaan “jika tidak sah, berhenti di sini” menyusut badan fungsi dan meratakan indentasinya.

return menutup babak kendali alur di dalam satu fungsi. Namun program nyata sering bekerja pada dua dimensi sekaligus: mengisi tabel, memeriksa matriks, atau menguji setiap pasangan kombinasi — tugas yang butuh loop di dalam loop. Chapter Nested Loop membawakan strukturnya beserta satu kejutan yang sudah kita bisikkan: break ternyata hanya tembus satu lapis.