Tiga header pustaka standar yang paling sering dibutuhkan program sehari-hari adalah math.h untuk perhitungan numerik, ctype.h untuk mengenali jenis karakter, dan time.h untuk menangani waktu serta tanggal. Topik ini membahas fungsi inti pada ketiganya beserta pola pemanggilan yang aman, termasuk kewajiban menyertakan flag -lm ketika program memakai pustaka matematika. Contoh-contohnya memakai nilai tetap, sehingga keluarannya dapat diulang dan diverifikasi kapan pun.
Fungsi matematika pada math.h#
Header math.h menyediakan fungsi matematis umum yang seluruhnya bekerja pada tipe double, yaitu menerima dan mengembalikan nilai pecahan berpresisi ganda. Fungsi yang paling sering dipakai antara lain sqrt untuk akar kuadrat, pow untuk perpangkatan, dan fabs untuk nilai mutlak. Pembulatan ke bawah serta ke atas ditangani floor dan ceil, sedangkan hypot menghitung panjang sisi miring segitiga siku-siku. Fungsi trigonometri seperti sin, cos, dan tan menerima sudut dalam radian, sedangkan log dan exp menangani logaritma natural serta fungsi eksponensial. Karena seluruhnya beroperasi pada double, argumen bertipe int dikonversi secara otomatis pada saat pemanggilan.
Pada gcc di Linux, fungsi math.h diimplementasikan dalam pustaka terpisah bernama libm, sehingga kompilasinya memerlukan flag -lm. Tanpa flag itu, pengait (linker) melaporkan pesan undefined reference to 'sqrt' meskipun prototipe fungsinya sudah tersedia lewat header. Perintah kompilasi berikut mengikuti pola yang dipakai sepanjang topik ini:
# kompilasi program matematika, flag -lm wajib untuk math.h
gcc fungsi-matematika.c -o fungsi-matematika -lmProgram berikut memanggil enam fungsi yang paling sering dibutuhkan, semuanya dengan argumen tetap:
#include <math.h>
#include <stdio.h>
int main(void)
{
double a = 2.0;
double b = -2.5;
printf("sqrt(2.0) = %.6f\n", sqrt(a));
printf("pow(2.0, 10.0) = %.1f\n", pow(a, 10.0));
printf("fabs(-2.5) = %.1f\n", fabs(b));
printf("floor(3.7) = %.1f\n", floor(3.7));
printf("ceil(3.2) = %.1f\n", ceil(3.2));
printf("hypot(3.0, 4.0) = %.1f\n", hypot(3.0, 4.0));
return 0;
}sqrt(2.0) = 1.414214
pow(2.0, 10.0) = 1024.0
fabs(-2.5) = 2.5
floor(3.7) = 3.0
ceil(3.2) = 4.0
hypot(3.0, 4.0) = 5.0Fungsi floor dan ceil tetap mengembalikan tipe double, sehingga hasilnya tercetak 3.0 dan 4.0 meskipun angkanya sudah bulat. Perbedaannya dengan cast ke int muncul pada bilangan negatif, karena cast memotong bagian pecahan ke arah nol, sedangkan floor selalu membulatkan ke bawah. Fungsi hypot menghitung akar kuadrat dari jumlah kuadrat dua argumennya dengan cara yang menghindari luapan (overflow) pada tahap perhitungan menengah. Karena itu, hypot lebih aman daripada menulis sqrt(a*a + b*b) sendiri.
Argumen yang berada di luar wilayah sah sebuah fungsi dilaporkan lewat mekanisme yang berbeda dari pesan error biasa. Misalnya sqrt pada argumen negatif mengembalikan NaN, kependekan dari not a number, dan menetapkan variabel errno dengan kode EDOM. Variabel errno tersebut adalah alat pelaporan error pustaka standar yang dibahas tuntas pada topik assert.h dan errno.h dalam modul ini.
Klasifikasi karakter pada ctype.h#
Header ctype.h berisi fungsi klasifikasi dan konversi karakter, seperti isalpha untuk huruf, isdigit untuk angka, dan isspace untuk spasi. Huruf besar serta kecil dikenali isupper dan islower, sedangkan toupper dan tolower mengubah kasusnya. Semua fungsi ini menerima satu argumen bertipe int dengan syarat nilainya berupa karakter yang dapat ditampung unsigned char, atau konstanta EOF. Nilai kembali fungsi klasifikasi berupa bilangan nol atau bukan nol, bukan benar dan salah, sehingga pengujiannya dilakukan langsung di dalam pernyataan if.
Syarat unsigned char itu penting ketika tipe char pada platform bersifat bertanda (signed). Apabila string memuat byte bernilai 128 sampai 255, misalnya pada teks bukan ASCII, nilai char bertanda tersebut menjadi negatif. Memasukkan nilai negatif itu ke fungsi ctype merupakan perilaku tak terdefinisi. Pola yang aman adalah mengonversi setiap karakter ke unsigned char lebih dahulu, sebagaimana dilakukan contoh berikut:
#include <ctype.h>
#include <stdio.h>
int main(void)
{
const char *teks = "Arsip 2026.txt";
int huruf = 0;
int angka = 0;
for (int i = 0; teks[i] != '\0'; i = i + 1) {
unsigned char c = (unsigned char)teks[i];
if (isalpha(c)) {
huruf = huruf + 1;
}
if (isdigit(c)) {
angka = angka + 1;
}
putchar(toupper(c));
}
putchar('\n');
printf("huruf: %d, angka: %d\n", huruf, angka);
return 0;
}ARSIP 2026.TXT
huruf: 8, angka: 4Perulangan membaca string satu karakter demi satu karakter, menghitung huruf dan angka, lalu mencetak versi huruf besarnya lewat toupper. Karakter yang bukan huruf, seperti spasi dan titik, diteruskan tanpa diubah karena toupper hanya menyentuh huruf kecil. Perlu dicatat bahwa isalpha hanya mengenali huruf ASCII, sehingga huruf beraksen maupun aksara non-Latin membutuhkan penanganan teks lebar dari header lain, misalnya wchar.h.
Waktu dan tanggal pada time.h#
Header time.h menangani waktu dalam dua bentuk. Bentuk pertama adalah time_t, yaitu tipe aritmetika yang menyimpan waktu sebagai jumlah detik sejak 1 Januari 1970 pukul 00:00 UTC, yang disebut epoch. Bentuk kedua adalah struct tm, yaitu kumpulan bidang waktu yang mudah dibaca manusia, seperti tahun, bulan, hari, jam, dan menit. Fungsi mktime mengubah struct tm menjadi time_t sekaligus menormalkan bidang yang tidak wajar, sedangkan strftime memformat struct tm menjadi teks tanggal sesuai penentu format yang diberikan.
Konvensi bidang pada struct tm perlu diingat karena bersifat tetap. Bidang tm_year menyimpan selisih tahun sejak 1900, sehingga tahun 2026 ditulis 126. Bidang tm_mon bernomor 0 sampai 11, sehingga November ditulis 10. Fungsi mktime justru membantu di sini, karena nilai yang melampaui batasnya, misalnya tm_mday bernilai 32, otomatis dinormalkan menjadi tanggal yang sah. Alur pengolahan waktu dirangkum diagram berikut:
Program berikut mengisi dua struct tm dengan nilai tetap, mengubahnya menjadi time_t, lalu menghitung selisihnya dengan difftime. Pendekatan ini menjaga keluaran tetap sama pada setiap eksekusi, berbeda dengan pemanggilan time yang mengambil waktu berjalan sistem.
#include <stdio.h>
#include <time.h>
int main(void)
{
struct tm mulai = {0};
struct tm akhir = {0};
mulai.tm_year = 2026 - 1900;
mulai.tm_mon = 10; /* November, bernomor 0-11 */
mulai.tm_mday = 2;
mulai.tm_hour = 9;
mulai.tm_min = 30;
akhir.tm_year = 2026 - 1900;
akhir.tm_mon = 10;
akhir.tm_mday = 12;
akhir.tm_hour = 9;
akhir.tm_min = 30;
time_t t1 = mktime(&mulai);
time_t t2 = mktime(&akhir);
char teks[64];
strftime(teks, sizeof teks, "%A, %d %B %Y pukul %H:%M", &mulai);
printf("mulai : %s\n", teks);
strftime(teks, sizeof teks, "%A, %d %B %Y pukul %H:%M", &akhir);
printf("akhir : %s\n", teks);
printf("selisih: %.0f detik\n", difftime(t2, t1));
printf("urutan hari mulai dalam tahun: %d\n", mulai.tm_yday + 1);
return 0;
}mulai : Monday, 02 November 2026 pukul 09:30
akhir : Thursday, 12 November 2026 pukul 09:30
selisih: 864000 detik
urutan hari mulai dalam tahun: 306Pemanggilan mktime mengisi ulang bidang tm_wday dan tm_yday sesuai tanggal yang dihitungnya, dan bidang itulah yang dicetak pada baris terakhir, yaitu hari ke-306 tahun 2026. Penentu %A dan %B pada strftime menghasilkan nama hari serta nama bulan sesuai locale, yaitu pengaturan wilayah yang aktif saat program berjalan. Tanpa pemanggilan setlocale, program memakai locale baku bernama C yang menampilkan teks Inggris. Penentu lain yang sering dipakai antara lain %d untuk tanggal dua digit, %H dan %M untuk jam serta menit, dan %Y untuk tahun empat digit.
Untuk waktu berjalan, fungsi time mengisi time_t dengan waktu sistem, lalu localtime menguraikannya menjadi struct tm zona waktu setempat dan gmtime menjadi waktu UTC. Kedua fungsi itu mengembalikan pointer ke struct tm milik pustaka, bukan salinan milik pemanggil, sehingga hasilnya perlu disalin apabila masih dibutuhkan setelah panggilan waktu berikutnya. Karena waktu sistem berubah seiring berjalannya, contoh pada topik ini sengaja tidak memakai ketiga fungsi itu agar keluaran tetap dapat diverifikasi.
Kesalahan umum#
Empat kesalahan berikut paling sering muncul ketika ketiga header ini pertama kali dipakai.
- Lupa flag -lm saat kompilasi. Pengait melaporkan
undefined reference to 'sqrt'seolah fungsi itu tidak ada, padahal prototipenya sudah tersedia. Solusinya menambahkan -lm di akhir perintah gcc, karena urutan flag pustaka pada gcc berpengaruh. - Mengoper char bertanda bernilai negatif ke fungsi ctype. Kesalahan ini muncul pada teks bukan ASCII dan berakibat perilaku tak terdefinisi. Selalu konversikan karakter ke unsigned char sebelum dipanggilkan ke isalpha dan kawan-kawannya.
- Mengisi struct tm tanpa mengikuti konvensi bidangnya. Mengisi tm_year dengan 2026 menghasilkan tahun 3926, dan mengisi tm_mon dengan 11 untuk Januari menghasilkan Desember. Tulis
2026 - 1900dan gunakan nomor bulan 0 sampai 11, atau biarkan mktime menormalkannya. - Memotong bilangan pecahan negatif dengan cast ke int. Cast
(int)-2.5menghasilkan -2 karena arahnya ke nol, sedangkan banyak kasus menghendaki -3.0 sebagaimana floor. Tentukan arah pembulatannya secara sadar sebelum memilih keduanya.
Ringkasan#
- Fungsi math.h seluruhnya bekerja pada double dan kompilasinya memerlukan flag -lm, dengan error wilayah sah dilaporkan berupa NaN dan kode EDOM pada errno.
- Fungsi ctype.h menerima nilai unsigned char atau EOF, sehingga karakter dari string bertanda wajib dikonversi lebih dahulu, dan nilai kembinya berupa nol atau bukan nol.
- time.h menyimpan waktu sebagai time_t berupa detik sejak epoch atau sebagai struct tm yang bidangnya mengikuti konvensi tetap, yaitu tm_year sejak 1900 dan tm_mon mulai dari 0.
- mktime mengubah struct tm menjadi time_t sambil menormalkan bidangnya, strftime memformat struct tm menjadi teks, dan difftime menghitung selisih dua waktu.
Referensi#
- sqrt(3) — Linux man-pages project — Dokumentasi fungsi matematika math.h beserta perilaku error wilayah sahnya.
- isalpha(3) — Linux man-pages project — Daftar lengkap fungsi klasifikasi karakter ctype.h dan syarat argumennya.
- ctime(3) — Linux man-pages project — Konversi antara time_t dan struct tm, termasuk konvensi bidang struct tm.
- Date and time utilities — cppreference.com — Ikhtisar seluruh fungsi time.h beserta penentu format strftime.