Menu

Tipe Data di C: int, float, char, double, dan Lainnya

Setiap variabel C punya tipe yang menentukan ukurannya dan apa yang bisa disimpannya. Berikut semua tipe dasar, ukuran sebenarnya, signed vs unsigned, sizeof, limits.h, dan apa yang terjadi saat overflow.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

Setiap variabel di C punya tipe, dipilih saat dideklarasikan dan tetap sepanjang umurnya. Tipe menentukan tiga hal: berapa byte yang dipakai variabel itu, bagaimana byte-byte itu ditafsirkan, dan operasi apa yang masuk akal untuknya.

Daftar tipe di C pendek. Kerumitannya ada di modifier.

Empat Tipe Dasar

  • char menyimpan satu byte. Dipakai untuk satu karakter ('A'), untuk byte-byte sebuah string, dan kadang sebagai integer yang sangat kecil.
  • int adalah tipe bilangan bulat andalan. Counter loop, ukuran, ID.
  • float dan double menyimpan bilangan real. double punya presisi kira-kira dua kali lipat.
  • void dalam arti tertentu adalah tipe keempat, tetapi artinya "tidak ada nilai": kamu tidak bisa mendeklarasikan variabel void, hanya memakainya sebagai tipe kembalian fungsi, daftar parameter kosong, atau pointer tanpa tipe.

Perhatikan akhiran f pada 3.14f. Tanpa akhiran itu, literalnya bertipe double, dan meng-assign-nya ke float diam-diam mengurangi presisi. Sebagian compiler memberi peringatan untuk ini.

Modifier: short, long, unsigned

Tipe integer dasar dilengkapi modifier yang mengubah ukuran atau tandanya.

Setiap tipe integer butuh format specifier-nya sendiri: %hd untuk short, %d untuk int, %ld untuk long, %lld untuk long long, %u untuk unsigned. Memakai yang salah adalah undefined behavior, bukan sekadar kesalahan pembulatan.

unsigned menghilangkan bit tanda dan menggandakan rentang positifnya. unsigned int menyimpan 0 sampai sekitar 4,3 miliar, alih-alih -2,1 sampai +2,1 miliar. Ini pilihan yang tepat untuk hal yang memang tidak mungkin negatif, seperti ukuran, jumlah byte, dan pola bit, tetapi menjadi jebakan untuk apa pun yang mungkin dikurangi sampai di bawah nol.

signed adalah default untuk int, short, long, dan long long, jadi kamu hampir tidak pernah menuliskannya. Satu-satunya tempat ini penting adalah char: apakah char biasa bersifat signed atau unsigned ditentukan oleh implementasi, jadi tulis signed char atau unsigned char kalau tandanya penting.

Ukuran: Apa yang Sebenarnya Kamu Dapat

Standar C menetapkan ukuran minimum, bukan ukuran pasti. Di mesin Linux, macOS, atau Windows 64-bit modern mana pun, kamu akan melihat ini:

TipeUkuran umumRentang umum
char1 byte-128 sampai 127 (atau 0 sampai 255)
short2 byte-32.768 sampai 32.767
int4 byte-2.147.483.648 sampai 2.147.483.647
long8 byte (4 di Windows)sekitar ±9,2 kuintiliun
long long8 bytesekitar ±9,2 kuintiliun
float4 byte~7 digit signifikan
double8 byte~15 digit signifikan
long double16 byte (bervariasi)lebih dari double

Baris long adalah yang sering menjebak: ukurannya 8 byte di Linux dan macOS, tetapi 4 byte di Windows 64-bit. Kode yang menganggap long bisa menampung nilai 64-bit tidak portabel. Gunakan long long, atau tipe dengan lebar pasti dari stdint.h (int32_t, uint64_t) kalau ukurannya memang bagian dari kebutuhan.

sizeof: Tanyakan ke Compiler

Jangan pernah menebak ukuran, ukur saja:

sizeof adalah operator, bukan fungsi, dan dievaluasi saat kompilasi. Hasilnya bertipe size_t, yang dicetak dengan %zu.

sizeof(char) dijamin tepat 1, karena itulah definisi byte di C. Semua tipe lain diukur relatif terhadapnya.

limits.h dan float.h

Rentang pasti untuk compiler-mu tersedia sebagai konstanta bernama:

Inilah nilai yang dipakai sebagai pembanding saat kamu perlu tahu apakah sebuah operasi akan overflow. Memeriksa if (a > INT_MAX - b) sebelum menghitung a + b adalah cara mendeteksi overflow sebelum terjadi. Itu penting, karena kamu tidak bisa mendeteksi signed overflow sesudahnya.

Integer Overflow

Apa yang terjadi saat sebuah nilai melampaui rentang tipenya sepenuhnya bergantung pada tandanya.

Unsigned overflow terdefinisi: nilainya melingkar modulo 2^N.

Kasus kedua itu adalah sumber bug yang nyata. Loop seperti for (unsigned i = n - 1; i >= 0; i--) tidak pernah berhenti, karena nilai unsigned selalu >= 0.

Signed overflow adalah undefined behavior. Bukan "melingkar", melainkan tidak terdefinisi. Compiler boleh menganggap hal itu tidak pernah terjadi dan melakukan optimasi berdasarkan anggapan tersebut, yang berarti pemeriksaan overflow yang ditulis setelah kejadian bisa dihapus:

int sum = a + b;
if (sum < a) { /* the compiler may remove this entirely */ }

Periksa sebelumnya, dengan memakai batasnya:

if (b > 0 && a > INT_MAX - b) {
    /* a + b would overflow - handle it */
}

Presisi Floating-Point

float dan double menyimpan angka dalam biner, dan sebagian besar pecahan desimal tidak punya bentuk biner yang pasti, sama seperti 1/3 tidak punya bentuk desimal yang pasti.

Aturan yang mengikutinya: jangan pernah membandingkan nilai floating-point dengan ==. Bandingkan selisih mutlaknya dengan toleransi kecil.

Dan jangan pernah memakai floating-point untuk uang. Simpan sen sebagai integer; long long berisi sen itu pasti, sedangkan double berisi dolar tidak.

Memilih Tipe

Daftar keputusan singkat yang mencakup sebagian besar kode:

  • Bilangan bulat: int, kecuali ada alasan lain. Inilah tipe yang paling efisien ditangani CPU dan tipe yang menjadi dasar semua aturan aritmetika.
  • Apa pun yang lebih besar dari 2 miliar: long long, atau int64_t dari stdint.h.
  • Ukuran, panjang, indeks array dari sizeof atau strlen: size_t. Tipe ini unsigned dan dijamin cukup besar untuk objek apa pun.
  • Desimal: double. Gunakan float hanya untuk menghemat setengah memori di array besar atau di hardware embedded tanpa unit presisi ganda.
  • Satu karakter dan byte mentah: char untuk teks, unsigned char untuk data biner.
  • True/false: bool dari stdbool.h; lihat boolean di C.
  • Lebar bit pasti (format file, protokol jaringan, register hardware): stdint.h, yaitu uint8_t, int16_t, uint32_t, dan seterusnya.

Mencampur Tipe

Saat kamu menggabungkan dua tipe berbeda dalam satu ekspresi, C mengonversinya diam-diam sebelum melakukan aritmetika. Biasanya ini membantu, tetapi sesekali berakibat fatal:

Yang pertama adalah pembagian integer: kedua operand bertipe int, jadi hasilnya int dan pecahannya dibuang. Yang ketiga lebih buruk: membandingkan nilai signed dengan nilai unsigned mengonversi yang signed menjadi unsigned, sehingga -1 berubah menjadi bilangan positif yang sangat besar.

Aturan konversi itu, dan cara mengendalikannya dengan cast eksplisit, dibahas di type casting di C.

Pertanyaan yang sering diajukan

Apa saja tipe data dasar di C?

Ada empat tipe dasar: char untuk satu karakter dan byte, int untuk bilangan bulat, float dan double untuk bilangan desimal. Modifier mengubah ukuran dan tandanya, yaitu short, long, long long, signed, dan unsigned, sehingga terbentuk kumpulan tipe yang lengkap.

Berapa byte ukuran int di C?

Hampir selalu 4 byte (32 bit) di sistem desktop dan server modern, dengan rentang sekitar -2,1 miliar sampai 2,1 miliar. Standar hanya menjamin minimal 2 byte, dan mikrokontroler 16-bit memang memakai 2. Gunakan sizeof(int) kalau kamu perlu tahu dengan pasti.

Apa perbedaan float dan double di C?

float berukuran 4 byte dengan sekitar 7 digit desimal signifikan; double berukuran 8 byte dengan sekitar 15 digit. Double adalah default untuk literal floating-point dan fungsi matematika, dan kecuali kamu menyimpan jutaan nilai atau menargetkan chip embedded, double adalah pilihan yang tepat.

Apa yang terjadi saat int mengalami overflow di C?

Untuk int signed, overflow adalah undefined behavior: compiler boleh membuatnya melingkar, mentok di batas, atau menghapus pemeriksaannya sama sekali saat optimasi. Untuk int unsigned, perilakunya sepenuhnya terdefinisi: nilainya melingkar modulo 2^N, jadi UINT_MAX + 1 adalah 0. Jangan pernah mengandalkan signed overflow.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai