Topik ini membahas pembuatan program C pertama beserta bedah anatomi setiap barisnya. Program dibuat, dikompilasi, dan dijalankan dari terminal, kemudian setiap komponen pentingnya dijelaskan satu per satu, mulai dari arahan #include, fungsi main, pernyataan, kurung kurawal, hingga nilai kembali. Setelah membaca topik ini, struktur program C terkecil dapat ditulis ulang dari nol tanpa perlu menghafal.
Menulis dan menjalankan program pertama#
Program C yang paling sering dijadikan contoh perdana adalah program yang mencetak teks Halo, dunia! ke layar. Program sekecil ini sudah memuat seluruh komponen wajib sebuah program C, sehingga tepat dijadikan bahan bedah anatomi. Simpan kode berikut sebagai berkas bernama halo.c di dalam folder kerja.
#include <stdio.h>
int main(void) {
printf("Halo, dunia!\n");
return 0;
}Halo, dunia!Kode sumber belum bisa dijalankan langsung oleh komputer karena komputer hanya mengerti kode mesin. Kode sumber terlebih dahulu dikompilasi, yaitu diterjemahkan menjadi kode mesin oleh program bernama kompiler (compiler). Gunakan gcc, kompiler yang paling umum tersedia di Linux:
# kompilasi halo.c menjadi program bernama halo
gcc halo.c -o halo
# jalankan program hasil kompilasi
./haloHalo, dunia!Perintah gcc halo.c -o halo membaca kode sumber lalu menghasilkan berkas program bernama halo. Opsi -o menetapkan nama berkas hasil kompilasi, sedangkan ./halo menjalankan program tersebut. Tanda ./ di awal berarti program dicari di folder saat ini, bukan di folder-folder sistem. Apabila opsi -o tidak diberikan, gcc menyimpan hasilnya dengan nama bawaan a.out, sehingga membiasakan opsi -o membuat hasil kompilasi mudah dikenali. Ekstensi .c pada nama berkas juga bukan sekadar kebiasaan, karena gcc mengenalinya sebagai kode sumber C.
Fungsi main sebagai pintu masuk program#
Setiap program C mulai dieksekusi dari fungsi main, sehingga setiap program utuh pasti memiliki fungsi ini. Sistem operasi memanggil main saat program dijalankan, dan program berakhir ketika main selesai. Kerangka paling kecil dari fungsi ini terlihat seperti berikut.
// tidak-dijalankan
int main(void) {
return 0;
}Bagian int di depan main menyatakan tipe nilai kembali (return value), yaitu jenis nilai yang dilaporkan fungsi kepada pemanggilnya. Nilai kembali bertipe int berarti fungsi melaporkan sebuah bilangan bulat, sedangkan kata void di dalam tanda kurung menyatakan fungsi ini tidak menerima parameter apa pun. Bentuk int main(void) adalah bentuk standar yang dipakai sepanjang jalur ini. Bentuk main yang menerima argumen baris perintah memerlukan parameter tambahan yang dibahas pada modul Preprosesor.
Pernyataan return 0; mengakhiri fungsi dan melaporkan angka nol kepada sistem operasi. Angka nol berarti program berakhir dengan sukses, sedangkan angka lain lazimnya berarti terjadi masalah. Status tersebut dapat diperiksa langsung dari terminal:
# jalankan halo lalu tampilkan kode status akhirnya
./halo
echo $?Halo, dunia!
0Variabel khusus $? di shell menyimpan status akhir perintah terakhir, dan nilainya ternyata memang 0 seperti yang dikembalikan oleh return 0;.
Arahan #include dan peran stdio.h#
Baris #include <stdio.h> bukan pernyataan C melainkan arahan (directive) untuk preprosesor, yaitu program yang menyiapkan kode sumber sebelum kompilasi sesungguhnya dimulai. Arahan ini menyuruh preprosesor menyisipkan isi berkas stdio.h ke posisi baris tersebut. Berkas stdio.h adalah berkas header (header), yaitu berkas berisi deklarasi fungsi-fungsi pustaka standar, dan nama stdio adalah singkatan dari standard input output.
Deklarasi penting yang dibawa stdio.h adalah deklarasi fungsi printf, fungsi yang dipakai program untuk mencetak teks. Apabila #include <stdio.h> sengaja dihapus, kompiler tidak lagi mengenal printf dan menolak melanjutkan kompilasi:
# salin halo.c tanpa baris pertamanya
tail -n +2 halo.c > tanpa-include.c
# coba kompilasi salinan tersebut, tampilkan empat baris pertama pesannya
gcc tanpa-include.c -o tanpa-include 2>&1 | head -n 4tanpa-include.c: In function ‘main’:
tanpa-include.c:3:5: error: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]
3 | printf("Halo, dunia!\n");
| ^~~~~~Pesan implicit declaration of function 'printf' muncul karena kompiler bertemu pemanggilan fungsi yang belum dideklarasikan. Dengan demikian, #include berfungsi memperkenalkan nama-nama fungsi pustaka kepada kompiler sebelum fungsi tersebut dipanggil. Perlu dicatat bahwa yang disertakan hanyalah deklarasinya. Kode asli fungsi printf berada di pustaka standar yang dirangkai pada tahap pengaitan, dan tahap itu dibahas pada topik Alur Kompilasi. Tanda kurung siku <stdio.h> menyatakan berkas header pustaka yang dicari di folder sistem, sedangkan bentuk "nama.h" dengan kutip ganda dipakai untuk berkas header buatan sendiri.
Pernyataan dan kurung kurawal#
Di dalam { dan } milik main terdapat badan fungsi, yaitu kumpulan pernyataan (statement) yang dijalankan berurutan dari atas ke bawah. Setiap pernyataan diakhiri tanda titik koma, dan tanda inilah yang memisahkan satu pernyataan dari pernyataan berikutnya. Dua pernyataan berikut dieksekusi sesuai urutan penulisannya.
// tidak-dijalankan
printf("Baris pertama.\n");
printf("Baris kedua.\n");Fungsi printf mencetak teks yang diberikan di dalam tanda kutip ganda. Karakter \n adalah notasi khusus untuk pindah baris, bukan dua karakter biasa. Tanpa \n, kursor tetap berada di baris yang sama setelah teks dicetak. Sebagian besar spasi dan pindah baris di dalam kode sumber tidak memengaruhi program, sehingga penataan baris bertujuan kenyamanan membaca. Yang benar-benar memengaruhi alur hanyalah pernyataan dan kurung kurawalnya.
Kurung kurawal wajib mengapit seluruh badan fungsi. Kurang satu kurung penutup membuat kompiler kebingungan menentukan batas fungsi, sehingga pesan error muncul jauh dari lokasi kesalahan sebenarnya. Karena itu, biasakan menuliskan pasangan { dan } sekaligus, lalu mengisi badannya di antara keduanya.
Kesalahan umum#
Dua kesalahan berikut paling sering dialami saat menulis program pertama. Keduanya ditunjukkan bersama pesan error aslinya agar dikenali ketika muncul di layar.
Pertama, titik koma yang hilang. Salin halo.c sambil menghapus satu titik koma, lalu kompilasi:
# buat salinan halo.c tanpa titik koma pada pernyataan printf
sed 's/!\\n");/!\\n")/' halo.c > salah.c
# kompilasi salinan tersebut
gcc salah.c -o salahsalah.c: In function ‘main’:
salah.c:4:29: error: expected ‘;’ before ‘return’
4 | printf("Halo, dunia!\n")
| ^
| ;
5 | return 0;
| ~~~~~~Pesan expected ';' before 'return' berarti kompiler mengharapkan titik koma sebelum kata return. Perhatikan bahwa nomor baris pada pesan menunjuk baris printf tempat titik koma hilang, sehingga pesan error ini cukup akurat sebagai petunjuk.
Kedua, menulis Main dengan huruf kapital. Nama fungsi di C bersifat peka huruf besar dan kecil (case sensitive), sehingga Main adalah nama lain yang tidak memiliki hubungan dengan main:
# ganti main menjadi Main pada salinan halo.c
sed 's/int main/int Main/' halo.c > mainbesar.c
# kompilasi salinan tersebut, tampilkan dua baris terakhir pesannya
gcc mainbesar.c -o mainbesar 2>&1 | tail -n 2(.text+0x17): undefined reference to `main'
collect2: error: ld returned 1 exit statusError undefined reference to 'main' muncul dari linker, yaitu program penggabung akhir yang mencari fungsi main sebagai titik masuk program. Karena yang ada hanya Main, pencarian gagal dan program tidak terbentuk. Kedua contoh di atas menunjukkan kebiasaan membaca error yang sehat, yaitu memulai dari baris pertama pesan karena error selanjutnya sering hanya merupakan akibat dari yang pertama.
Ringkasan#
- Setiap program C utuh memiliki fungsi
mainsebagai titik masuk eksekusi, danreturn 0;melaporkan keberhasilan kepada sistem operasi. #include <stdio.h>menyisipkan deklarasi fungsi pustaka standar, antara lainprintf, sebelum kompilasi dimulai.- Pernyataan dijalankan berurutan dan diakhiri titik koma, sedangkan kurung kurawal mengapit badan fungsi.
- Kompilasi dilakukan dengan
gcc halo.c -o halo, lalu program dijalankan dengan./halo.
Referensi#
- main function — cppreference
— Penjelasan bentuk fungsi
main, nilai kembali, dan status akhir program. - printf, fprintf, sprintf, snprintf — cppreference
— Dokumentasi resmi fungsi
printfpada pustaka standar C.