Literal adalah nilai konstan yang ditulis langsung di kode sumber, misalnya 42, 3.14f, 'A', atau "Halo". Setiap literal memiliki tipe yang ditentukan oleh bentuk penulisannya, dan tipe ini menentukan bagaimana compiler mengalokasikan memori serta operasi apa yang valid. Pada Chapter ini kita akan memetakan empat jenis literal utama di C: integer, floating point, karakter, dan string. Memahami tipe literal penting karena kesalahan tipe pada literal adalah sumber bug klasik—misalnya 0 bertipe int sedangkan 0L bertipe long, dan printf memperlakukan keduanya berbeda.
Literal Integer dan Suffix-nya #
Literal integer ditulis sebagai deretan digit. Tipe default literal integer bergantung pada nilai dan keberadaan suffix. Tanpa suffix, literal integer akan bertipe int jika muat, kemudian long int, kemudian long long int (sesuai urutan ini). Suffix U/u memaksa tipe unsigned, L/l memaksa tipe long, dan LL/ll memaksa tipe long long. Kombinasi seperti UL atau ULL menghasilkan tipe unsigned dengan ukuran sesuai.
#include <stdio.h>
int main(void) {
/* Literal integer */
int dec = 42;
int neg = -7;
long lval = 100L;
long long llval = 9000000000LL;
unsigned int uval = 100u;
/* Literal floating point */
float fval = 3.14f;
double dval = 2.71828;
double sci = 6.022e23;
printf("dec = %d, neg = %d\n", dec, neg);
printf("lval = %ld, llval = %lld, uval = %u\n", lval, llval, uval);
printf("fval = %.2f, dval = %.5f, sci = %.3e\n", fval, dval, sci);
return 0;
}Output yang Dihasilkan:
dec = 42, neg = -7
lval = 100, llval = 9000000000, uval = 100
fval = 3.14, dval = 2.71828, sci = 6.022e+23Mari kita telaah baris-baris kode di atas:
- Baris 5 (
int dec = 42;): literal42bertipeint(default untuk bilangan bulat kecil). - Baris 6 (
int neg = -7;): tanda minus adalah operator unary, bukan bagian dari literal; literal sebenarnya adalah7bertipeint, lalu di-negate. - Baris 7 (
long lval = 100L;): suffixLmembuat literal bertipelong. - Baris 8 (
long long llval = 9000000000LL;): suffixLLwajib karena nilai melebihiINT_MAX. - Baris 9 (
unsigned int uval = 100u;): suffixumembuat literal bertipeunsigned int. - Baris 12 (
float fval = 3.14f;): suffixfmembuat literal bertipefloat; tanpa suffix, literal desimal selalu bertipedouble. - Baris 13 (
double dval = 2.71828;): literal tanpa suffix bertipedoublesecara default. - Baris 14 (
double sci = 6.022e23;): notasi ilmiahemembuat literal bertipedouble.
Literal Karakter dan String #
Literal karakter diapit tanda kutip tunggal ('A'), sedangkan literal string diapit tanda kutip ganda ("Halo"). Walaupun mirip secara visual, keduanya berbeda tipe: literal karakter bertipe int di C (bukan char!), sedangkan literal string bertipe array of char dengan elemen tambahan '\0' di akhir sebagai penanda akhir string.
#include <stdio.h>
int main(void) {
/* Literal karakter */
char letter = 'A';
char digit = '0';
char newline = '\n';
/* Literal string */
const char *greeting = "Halo, Dunia!";
const char *kosong = "";
printf("letter = %c (kode %d)\n", letter, letter);
printf("digit = %c (kode %d)\n", digit, digit);
printf("newline = kode %d\n", newline);
printf("greeting = %s (panjang %zu)\n", greeting, sizeof("Halo, Dunia!") - 1);
printf("kosong = '%s' (panjang %zu)\n", kosong, sizeof("") - 1);
return 0;
}Output yang Dihasilkan:
letter = A (kode 65)
digit = 0 (kode 48)
newline = kode 10
greeting = Halo, Dunia! (panjang 12)
kosong = '' (panjang 0)Pada baris 6, literal 'A' sebenarnya bertipe int bernilai 65, lalu dikonversi ke char saat ditugaskan. Pada baris 7, '0' (kode ASCII 48) berbeda dengan angka 0 (literal integer). Pada baris 11, "Halo, Dunia!" adalah array of char berukuran 13 (12 karakter + 1 null terminator). Pada baris 14, sizeof("Halo, Dunia!") menghasilkan 13, sehingga panjang string sebenarnya adalah 12 setelah dikurangi 1 byte untuk null terminator. Pada baris 15, string kosong "" tetap mengandung satu byte '\0'; sizeof("") adalah 1, sehingga panjang string 0.
Literal dengan Berbagai Basis #
Literal integer bisa ditulis dalam tiga basis: desimal (basis 10), heksadesimal (basis 16, diawali 0x), dan oktal (basis 8, diawali 0). Sejak C23, basis biner (basis 2, diawali 0b) juga distandarkan; sebelum C23, basis biner adalah ekstensi GCC dan Clang.
#include <stdio.h>
int main(void) {
/* Literal dengan berbagai basis */
int hex1 = 0xFF; /* 255 */
long hexL = 0xDEADBEEFL; /* nilai besar, perlu long */
int oct = 0777; /* 511 */
int bin = 0b1010; /* 10 (GCC extension; standar C23) */
printf("hex1 = %d\n", hex1);
printf("hexL = %ld\n", hexL);
printf("oct = %d\n", oct);
printf("bin = %d\n", bin);
/* Literal dengan suffix kombinasi */
unsigned long ul = 100UL;
unsigned long long ull = 100ULL;
printf("ul = %lu\n", ul);
printf("ull = %llu\n", ull);
return 0;
}Output yang Dihasilkan:
hex1 = 255
hexL = 3735928559
oct = 511
bin = 10
ul = 100
ull = 100Pada baris 6, 0xFF menghasilkan 15*16 + 15 = 255. Pada baris 7, 0xDEADBEEF adalah angka heksadesimal besar yang melebihi INT_MAX; suffix L membuatnya bertipe long. Pada baris 8, 0777 diinterpretasikan sebagai oktal: 7*64 + 7*8 + 7 = 511. Pada baris 9, 0b1010 adalah basis biner (ekstensi di C11, standar di C23) yang menghasilkan 10. Pada baris 13, suffix UL menggabungkan unsigned dan long menjadi unsigned long. Pada baris 14, suffix ULL menghasilkan unsigned long long.
Tipe Default Literal dan Promosi #
Saat sebuah literal integer ditulis tanpa suffix, compiler memilih tipe terkecil yang bisa menampung nilai tersebut dari daftar berurutan: int → long int → long long int. Untuk literal desimal, urutan ini menggunakan versi signed; untuk literal heksadesimal/oktal/biner, urutan menggunakan versi unsigned jika nilai melebihi batas signed. Tipe literal menentukan format specifier yang tepat untuk printf dan tipe hasil ekspresi yang melibatkan literal tersebut.
Dengan pemahaman empat jenis literal ini, kita siap masuk ke pembahasan representasi angka yang lebih mendalam—melihat bagaimana bilangan disimpan dalam bentuk biner, heksadesimal, dan oktal pada level bit.