Standar C tidak menentukan ukuran pasti tipe int, long, dan long long dalam byte. Yang dijamin hanyalah urutan: short lebih kecil atau sama dengan int, dan int lebih kecil atau sama dengan long. Untuk memenuhi kebutuhan program yang spesifik—hemat memori pada perangkat kecil, atau menampung angka raksasa—C menyediakan modifier short, long, dan long long. Pada Chapter ini kita akan memetakan ukuran aktual di platform modern, kapan memakai masing-masing, dan kenapa tipe fixed-width seperti int32_t sering menjadi pilihan yang lebih aman.
Hierarki Ukuran Integer #
Standar C (ISO/IEC 9899:2017 bagian 5.2.4.2) menetapkan batas minimum, tetapi ukuran aktual bergantung pada ABI platform. Pada x86_64 Linux dengan GCC, ukuran yang umum adalah:
| Tipe | Ukuran (byte) | Rentang minimum standar |
|---|---|---|
short | 2 | -32.768 sampai 32.767 |
int | 4 | -32.768 sampai 32.767 (jaminan minimum) |
long | 8 (Linux/macOS) / 4 (Windows) | -2.147.483.648 sampai 2.147.483.647 |
long long | 8 | -9.223.372.036.854.775.808 sampai 9.223.372.036.854.775.807 |
Perhatikan bahwa long di Windows ukurannya 4 byte (model LLP64), sedangkan di Linux/macOS ukurannya 8 byte (model LP64). Inilah salah satu sumber bug klasik ketika kode C dipindahkan antar sistem operasi.
#include <stdio.h>
#include <limits.h>
int main(void) {
short s = 1000;
int i = 1000000;
long l = 100000000L;
long long ll = 9000000000LL;
printf("short = %hd\n", s);
printf("int = %d\n", i);
printf("long = %ld\n", l);
printf("long long = %lld\n", ll);
printf("Ukuran short = %zu byte\n", sizeof(short));
printf("Ukuran int = %zu byte\n", sizeof(int));
printf("Ukuran long = %zu byte\n", sizeof(long));
printf("Ukuran long long = %zu byte\n", sizeof(long long));
printf("SHRT_MAX = %hd\n", SHRT_MAX);
printf("INT_MAX = %d\n", INT_MAX);
printf("LONG_MAX = %ld\n", LONG_MAX);
printf("LLONG_MAX = %lld\n", LLONG_MAX);
return 0;
}Output yang Dihasilkan:
short = 1000
int = 1000000
long = 100000000
long long = 9000000000
Ukuran short = 2 byte
Ukuran int = 4 byte
Ukuran long = 8 byte
Ukuran long long = 8 byte
SHRT_MAX = 32767
INT_MAX = 2147483647
LONG_MAX = 9223372036854775807
LLONG_MAX = 9223372036854775807Mari kita telaah baris-baris kode di atas:
- Baris 6 (
short s = 1000;):shortdijamin minimal 16 bit; di x86_64 GCC tetap 2 byte. - Baris 8 (
long l = 100000000L;): suffixLmenandakan literal bertipelong; tanpa suffix, literal100000000masih muat diintsehingga tidak menjadi masalah, tetapiLmembuat intensi eksplisit. - Baris 9 (
long long ll = 9000000000LL;): suffixLLwajib karena nilai9.000.000.000melebihiINT_MAX(2.147.483.647). - Baris 11 (
%hd): specifier untukshort(half-decimal);%dsendiri juga bisa dipakai karena integer promotion mengubahshortmenjadiintsaat dilewatkan keprintf. - Baris 13-14 (
%ld,%lld): specifier khusus untuklongdanlong long. - Baris 22 (
LLONG_MAX): konstanta darilimits.hyang menyatakan batas ataslong long; nilainya2^63 - 1.
Kapan Memakai long long #
Tipe long long diperkenalkan di C99 dan menjamin ukuran minimal 64 bit. Tipe ini wajib dipakai ketika nilai yang ditampung bisa melebihi INT_MAX (2.147.483.647). Contoh klasik adalah jumlah penduduk dunia (~7.9 miliar), transaksi finansial besar (dalam satuan rupiah), atau hasil perkalian dua angka yang masing-masing sudah besar.
#include <stdio.h>
#include <limits.h>
int main(void) {
/* Kasus yang membutuhkan long long */
long long penduduk_dunia = 7900000000LL; /* 7.9 miliar */
long long jarak_bulan_km = 384400LL; /* jarak Bumi-Bulan */
long long hasil = penduduk_dunia * 2;
printf("Penduduk dunia = %lld\n", penduduk_dunia);
printf("Jarak Bumi-Bulan = %lld km\n", jarak_bulan_km);
printf("Penduduk x2 = %lld\n", hasil);
/* Mengapa int tidak cukup? */
int attempt = (int)penduduk_dunia; /* truncate */
printf("Cast ke int = %d (overflow!)\n", attempt);
return 0;
}Output yang Dihasilkan:
Penduduk dunia = 7900000000
Jarak Bumi-Bulan = 384400 km
Penduduk x2 = 15800000000
Cast ke int = -689934592 (overflow!)Pada baris 7, nilai 7.900.000.000 melebihi INT_MAX (2.147.483.647), sehingga long long wajib dipakai. Pada baris 9, perkalian penduduk_dunia * 2 menghasilkan 15.800.000.000 yang juga masih muat di long long. Pada baris 14, cast (int)penduduk_dunia memotong 32 bit teratas sehingga sisanya diinterpretasikan sebagai int bertanda—hasilnya -689.934.592 yang jelas salah. Ini menunjukkan bahaya mengubah tipe yang lebih besar ke tipe yang lebih kecil.
Tipe Fixed-Width dari stdint.h #
Karena ukuran int dan long tidak konsisten antar platform, C99 memperkenalkan header <stdint.h> yang menyediakan tipe fixed-width: int8_t, int16_t, int32_t, int64_t, serta versi unsigned-nya (uint8_t dst). Tipe-tipe ini menjamin ukuran tepat, bukan minimal. Untuk menampilkan tipe-tipe ini dengan printf, gunakan makro PRId16, PRId32, PRId64 dari header <inttypes.h> agar portable di semua platform.
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
int main(void) {
/* Tipe fixed-width dari <stdint.h> */
int16_t a = 32000;
int32_t b = 2000000000;
int64_t c = 9000000000LL;
uint8_t byte_val = 250;
printf("int16_t = %" PRId16 "\n", a);
printf("int32_t = %" PRId32 "\n", b);
printf("int64_t = %" PRId64 "\n", c);
printf("uint8_t = %" PRIu8 "\n", byte_val);
printf("Ukuran int16_t = %zu byte\n", sizeof(int16_t));
printf("Ukuran int64_t = %zu byte\n", sizeof(int64_t));
return 0;
}Output yang Dihasilkan:
int16_t = 32000
int32_t = 2000000000
int64_t = 9000000000
uint8_t = 250
Ukuran int16_t = 2 byte
Ukuran int64_t = 8 bytePada baris 11, makro PRId16 direntangkan oleh preprocessor menjadi format specifier yang tepat untuk int16_t di platform saat ini—misalnya "hd" di platform yang short 16 bit, atau "d" jika int 16 bit. Pendekatan ini menghindari bug format specifier yang muncul saat kode dipindahkan antar platform.
short untuk Hemat Memori #
Tipe short (2 byte) jarang dipakai pada kode desktop modern karena penghematan memorinya tidak signifikan. Tipe ini lebih sering muncul pada embedded system dengan RAM terbatas, atau pada format file biner yang spesifik mendefinisikan field 16-bit (misalnya format WAV atau PNG). Untuk komputasi biasa, int biasanya sama cepatnya dengan short karena prosesor modern dioptimalkan untuk operasi 32-bit.
Dengan modifier short, long, dan long long, kita punya fleksibilitas memilih ukuran tipe. Selanjutnya, kita akan belajar cara memeriksa ukuran tipe secara programatik menggunakan operator sizeof dan tipe size_t.