C bukan bahasa yang dipakai untuk menulis aplikasi web dashboard atau skrip analisis data sekali jalan. C dipakai pada lapisan yang membutuhkan kinerja tinggi, kontrol langsung terhadap perangkat keras, dan ketergantungan minimum pada runtime lain. Pada Chapter ini kita akan melihat bidang-bidang utama yang memanfaatkan C, sekaligus mencoba beberapa API standar yang menjadi pintu masuk C ke sistem operasi. Dengan memahami konteks pemakaian C, kita akan tahu kapan harus memilih C dan kapan sebaiknya memilih bahasa lain.
Bidang Pemakaian Utama C #
C hadir di banyak lapisan fundamental perangkat lunak modern. Beberapa bidang yang sangat bergantung pada C antara lain:
- Sistem operasi: kernel Linux, kernel FreeBSD, dan sebagian besar kernel Windows ditulis dalam C.
- Sistem tertanam (embedded): firmware mikrokontroler, driver perangkat, dan kode real-time di perangkat IoT.
- Database engine: SQLite, PostgreSQL, MySQL, dan Redis semuanya ditulis dalam C.
- Interpreter dan runtime bahasa lain: CPython (Python), PHP Zend Engine, Lua, dan Ruby MRI semuanya diimplementasikan dalam C.
- Library sistem:
glibc,musl, OpenSSL,zlib, danlibcurlmenjadi fondasi yang dipakai bahasa lain. - Game engine: banyak komponen kinerja-kritis di Unreal Engine dan Unity ditulis dalam C atau C++.
- Compiler dan tools: GCC, Clang, Make, dan CMake semuanya berbasis C/C++.
Cocoknya C untuk bidang-bidang tersebut berasal dari tiga sifat utama: kompilasi ke kode mesin asli yang cepat, akses langsung ke system call lewat header POSIX dan Windows API, serta kontrol penuh terhadap alokasi memori.
Mengakses Informasi Sistem Operasi #
Salah satu kekuatan C adalah kemudahan mengakses informasi sistem operasi lewat API standar. Pada sistem POSIX (Linux, macOS, BSD), header <sys/utsname.h> menyediakan fungsi uname yang mengembalikan nama sistem, versi kernel, dan arsitektur mesin. Berikut contoh kode yang memakai API tersebut:
#include <stdio.h>
#include <sys/utsname.h>
int main(void) {
struct utsname info;
if (uname(&info) == 0) {
printf("Sistem operasi : %s\n", info.sysname);
printf("Hostname : %s\n", info.nodename);
printf("Versi kernel : %s\n", info.release);
printf("Arsitektur : %s\n", info.machine);
} else {
printf("Gagal mengambil info sistem.\n");
}
return 0;
}Output yang Dihasilkan:
Sistem operasi : Linux
Hostname : c-6acd9659-14810412-33ddf6d3a64e
Versi kernel : 5.10.134-013.15.kangaroo.al8.x86_64
Arsitektur : x86_64Mari kita telaah baris-baris kode di atas:
- Baris 2 (
#include <sys/utsname.h>): header POSIX yang mendefinisikan tipestruct utsnamedan fungsiuname. - Baris 5 (
struct utsname info;): mendeklarasikan variabelinfobertipestruct utsnameyang akan menampung hasil panggilanuname. - Baris 6 (
uname(&info) == 0): memanggil fungsiunamedengan alamatinfo; fungsi mengembalikan0bila sukses. - Baris 7-10 (
printf(...)): mencetak field-field struktur sepertiinfo.sysnamedaninfo.machine. - Baris 12 (
else): bilaunamegagal (misalnya dipanggil di lingkungan non-POSIX), program mencetak pesan kesalahan.
Membaca Environment Variable #
Banyak program C membaca konfigurasi dari environment variable yang diatur shell sebelum program dijalankan. Standar C menyediakan fungsi getenv di header <stdlib.h> untuk mengambil nilai berdasarkan nama. Fungsi ini mengembalikan pointer ke string, atau NULL bila variabel tidak ditemukan.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
const char *user = getenv("USER");
const char *shell = getenv("SHELL");
const char *home = getenv("HOME");
printf("USER = %s\n", user ? user : "(kosong)");
printf("SHELL = %s\n", shell ? shell : "(kosong)");
printf("HOME = %s\n", home ? home : "(kosong)");
return 0;
}Output yang Dihasilkan:
USER = z
SHELL = /bin/bash
HOME = /home/zMari kita telaah baris-baris kode di atas:
- Baris 2 (
#include <stdlib.h>): menyertakan header standar yang mendeklarasikan fungsigetenv. - Baris 5 (
const char *user = getenv("USER");): pointeruserdiisi dengan alamat string nilai variabelUSER, atauNULLbila variabel tidak ada. - Baris 8 (
user ? user : "(kosong)"): operator ternary memilihuserbila tidakNULL, jika tidak dipilih string literal"(kosong)". - Baris 9-10: pola yang sama dipakai untuk variabel
SHELLdanHOME.
Ekosistem dan Komunitas #
Komunitas C tersebar di banyak proyek open source besar. Berikut daftar proyek populer yang kode sumbernya bisa kita pelajari langsung:
#include <stdio.h>
#include <string.h>
int main(void) {
const char *proyek[] = {
"Kernel Linux",
"Git",
"SQLite",
"curl",
"Redis",
"Nginx"
};
size_t n = sizeof(proyek) / sizeof(proyek[0]);
printf("Daftar proyek open source berbasis C:\n");
for (size_t i = 0; i < n; i++) {
printf(" %zu. %s (%zu byte)\n", i + 1, proyek[i], strlen(proyek[i]));
}
return 0;
}Output yang Dihasilkan:
Daftar proyek open source berbasis C:
1. Kernel Linux (12 byte)
2. Git (3 byte)
3. SQLite (6 byte)
4. curl (4 byte)
5. Redis (5 byte)
6. Nginx (5 byte)Mari kita telaah baris-baris kode di atas:
- Baris 5-12 (
const char *proyek[] = {...};): array berisi enam pointer ke string literal. - Baris 13 (
sizeof(proyek) / sizeof(proyek[0])): idiom standar C untuk menghitung jumlah elemen array secara statis pada saat kompilasi. - Baris 15 (
for (size_t i = 0; i < n; i++)): loop memakai tipesize_tuntuk indeks karena membandingkan dengannyang bertipesize_t. - Baris 16 (
strlen(proyek[i])): menghitung panjang string tanpa termasuk karakter terminator nol. - Baris 16 (
%zu): format specifier yang benar untuk mencetaksize_t.