1. Pengenalan C
C adalah bahasa pemrograman prosedural yang dikembangkan oleh Dennis Ritchie antara tahun 1969-1973 di Bell Labs. C awalnya dikembangkan untuk menulis ulang sistem operasi UNIX.
Karakteristik Utama C:
- Prosedural - Berbasis fungsi dan prosedur
- Mid-level - Kombinasi high-level dan low-level
- Static typing - Tipe data ditentukan saat kompilasi
- Manual memory management - Programmer mengelola memory sendiri
- Portable - Program C bisa dijalankan di berbagai platform
- Fast - Sangat cepat karena dekat dengan hardware
#include <stdio.h>
int main() {
// Menampilkan teks ke console
printf("Hello, World!\n");
printf("Selamat belajar C!\n");
return 0; // Menandakan program sukses
}
#include <stdio.h> digunakan untuk mengimpor library standard input-output.
Fungsi printf() berasal dari library ini. \n adalah newline (pindah baris).
2. Instalasi & Compiler
Compiler C yang populer:
Instalasi GCC di berbagai OS:
sudo apt update
sudo apt install build-essential
gcc --version # Cek versi
xcode-select --install # Install Command Line Tools
# atau via Homebrew
brew install gcc
1. Download MinGW dari https://sourceforge.net/projects/mingw/
2. Jalankan installer
3. Pilih mingw32-gcc-g++ dan mingw32-base
4. Tambahkan C:\MinGW\bin ke PATH environment
Cara kompilasi dan menjalankan:
# Kompilasi program
gcc program.c -o program
# Jalankan program
./program # Linux/macOS
program.exe # Windows
# Kompilasi dengan warning lengkap
gcc -Wall -Wextra program.c -o program
# Kompilasi dengan optimasi
gcc -O2 program.c -o program
# Kompilasi dengan debug symbols
gcc -g program.c -o program
3. Sintaks Dasar
Aturan dasar penulisan C:
- • File C berekstensi
.c - • Entry point adalah fungsi
main() - • Setiap statement diakhiri dengan titik koma (;)
- • Blok kode menggunakan kurung kurawal { }
- • Komentar:
//untuk single line (C99),/* */untuk multi-line - • Case-sensitive (huruf besar/kecil dibedakan)
- • Setiap program harus memiliki fungsi
main()
main() biasanya mengembalikan int.
return 0; menandakan program sukses, selain 0 menandakan error.
/*
Ini komentar multi-line
Bisa untuk deskripsi program
Author: alzzdevmaret
*/
// Single line comment
#include <stdio.h> // untuk printf, scanf
#include <stdlib.h> // untuk fungsi umum
#define PI 3.14159 // Mendefinisikan konstanta
// Fungsi main - entry point
int main() {
// Deklarasi variabel
int umur = 20;
// Menampilkan output
printf("Hello, World!\n");
printf("Umur: %d\n", umur);
return 0; // Program sukses
} // Akhir blok main
4. Variabel & Tipe Data
Tipe data dasar di C:
| Tipe | Format Specifier | Ukuran | Range |
|---|---|---|---|
char | %c | 1 byte | -128 s/d 127 atau 0-255 |
unsigned char | %c | 1 byte | 0 s/d 255 |
short | %hd | 2 bytes | -32,768 s/d 32,767 |
unsigned short | %hu | 2 bytes | 0 s/d 65,535 |
int | %d | 4 bytes | -2,147,483,648 s/d 2,147,483,647 |
unsigned int | %u | 4 bytes | 0 s/d 4,294,967,295 |
long | %ld | 8 bytes | -2^63 s/d 2^63-1 |
unsigned long | %lu | 8 bytes | 0 s/d 2^64-1 |
float | %f | 4 bytes | 1.2E-38 s/d 3.4E+38 |
double | %lf | 8 bytes | 2.3E-308 s/d 1.7E+308 |
Aturan penamaan variabel:
- Bisa huruf, angka, underscore (_)
- Tidak boleh diawali angka
- Case-sensitive (umur != Umur)
- Tidak boleh menggunakan keyword C (int, if, while, dll)
#include <stdio.h>
int main() {
// Deklarasi dan inisialisasi variabel
int umur = 20;
float tinggi = 175.5;
double pi = 3.14159265359;
char grade = 'A';
char nama[] = "Budi"; // Array of characters (string)
// Menampilkan dengan format specifier
printf("Umur: %d tahun\n", umur);
printf("Tinggi: %.1f cm\n", tinggi); // .1f = 1 desimal
printf("Nilai pi: %.10lf\n", pi); // .10lf = 10 desimal
printf("Grade: %c\n", grade);
printf("Nama: %s\n", nama);
// Konstanta dengan const
const int MAX_SISWA = 100;
// MAX_SISWA = 200; // ERROR! konstanta tidak bisa diubah
// Multiple deklarasi
int a, b, c;
a = b = c = 10;
// Inisialisasi langsung
int x = 5, y = 10, z = 15;
printf("x=%d, y=%d, z=%d\n", x, y, z);
return 0;
}
float untuk menghemat memory, double untuk presisi tinggi.
Untuk integer, pilih tipe yang sesuai dengan range yang dibutuhkan.
5. Operator
Jenis-jenis operator di C:
Aritmatika
+ tambah
- kurang
* kali
/ bagi
% modulus (sisa bagi)
Perbandingan
== sama dengan
!= tidak sama
> lebih besar
< lebih kecil
>= lebih besar sama dengan
<= lebih kecil sama dengan
Logika
&& AND
|| OR
! NOT
Penugasan
= assignment
+= a += b (a = a + b)
-= a -= b
*= a *= b
/= a /= b
%= a %= b
Increment/Decrement
++ increment (a++)
-- decrement (a--)
Bitwise
& AND
| OR
^ XOR
~ NOT
<< left shift
>> right shift
#include <stdio.h>
int main() {
int a = 10, b = 3;
// Aritmatika
printf("a + b = %d\n", a + b);
printf("a - b = %d\n", a - b);
printf("a * b = %d\n", a * b);
printf("a / b = %d\n", a / b); // integer division = 3
printf("a %% b = %d\n", a % b); // modulus = 1
// Perbandingan (menghasilkan 0 atau 1)
printf("a == b? %d\n", a == b);
printf("a != b? %d\n", a != b);
printf("a > b? %d\n", a > b);
// Logika
int x = 1, y = 0;
printf("x && y: %d\n", x && y);
printf("x || y: %d\n", x || y);
printf("!x: %d\n", !x);
// Increment/Decrement
int c = 5;
printf("c = %d\n", c);
printf("c++ = %d\n", c++); // post-increment (tampilkan dulu, baru tambah)
printf("setelah c++ = %d\n", c);
int d = 5;
printf("++d = %d\n", ++d); // pre-increment (tambah dulu, baru tampilkan)
// Operator penugasan
int e = 10;
e += 5; // sama dengan e = e + 5
printf("e += 5 = %d\n", e);
e *= 2;
printf("e *= 2 = %d\n", e);
// Operator ternary (conditional)
int umur = 18;
char *status = (umur >= 17) ? "Boleh buat SIM" : "Belum boleh";
printf("Status: %s\n", status);
return 0;
}
6. Control Flow (Percabangan)
Struktur if-else:
if (kondisi) {
// kode jika kondisi true
} else if (kondisi2) {
// kode jika kondisi2 true
} else {
// kode jika semua false
}
Struktur switch-case:
switch (ekspresi) {
case nilai1:
// kode
break;
case nilai2:
// kode
break;
default:
// kode default
}
Catatan: break penting untuk keluar dari switch. Tanpa break, akan lanjut ke case berikutnya (fall-through).
#include <stdio.h>
int main() {
int nilai = 85;
// if-else
if (nilai >= 90) {
printf("Grade A\n");
} else if (nilai >= 80) {
printf("Grade B\n");
} else if (nilai >= 70) {
printf("Grade C\n");
} else if (nilai >= 60) {
printf("Grade D\n");
} else {
printf("Grade E (Tidak lulus)\n");
}
// Nested if
int umur = 20;
int memilikiSIM = 1; // 1 = true, 0 = false
if (umur >= 17) {
if (memilikiSIM) {
printf("Boleh mengemudi\n");
} else {
printf("Boleh mengemudi tapi belum punya SIM\n");
}
} else {
printf("Belum cukup umur untuk mengemudi\n");
}
// Switch case
int hari = 3;
switch (hari) {
case 1:
printf("Senin\n");
break;
case 2:
printf("Selasa\n");
break;
case 3:
printf("Rabu\n");
break;
case 4:
printf("Kamis\n");
break;
case 5:
printf("Jumat\n");
break;
case 6:
printf("Sabtu\n");
break;
case 7:
printf("Minggu\n");
break;
default:
printf("Hari tidak valid\n");
}
// Contoh fall-through (tanpa break)
int angka = 2;
switch (angka) {
case 1:
case 2:
case 3:
printf("Angka antara 1-3\n");
break;
default:
printf("Angka lain\n");
}
return 0;
}
7. Perulangan (Loops)
Jenis perulangan di C:
1. for loop
for (inisialisasi; kondisi; increment) {
// kode
}
2. while loop
while (kondisi) {
// kode
}
3. do-while loop
do {
// kode (minimal dijalankan sekali)
} while (kondisi);
Kontrol loop:
break- keluar dari loopcontinue- skip iterasi saat ini
#include <stdio.h>
int main() {
// 1. For loop
printf("For loop: 1 s/d 5\n");
for (int i = 1; i <= 5; i++) {
printf("%d ", i);
}
printf("\n\n");
// For loop dengan decrement
printf("For loop mundur: 5 s/d 1\n");
for (int i = 5; i >= 1; i--) {
printf("%d ", i);
}
printf("\n\n");
// 2. While loop
printf("While loop:\n");
int j = 1;
while (j <= 5) {
printf("%d ", j);
j++;
}
printf("\n\n");
// 3. Do-while loop
printf("Do-while loop:\n");
int k = 1;
do {
printf("%d ", k);
k++;
} while (k <= 5);
printf("\n\n");
// 4. Nested loop (perkalian)
printf("Tabel perkalian 5x5:\n");
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= 5; j++) {
printf("%4d", i * j);
}
printf("\n");
}
printf("\n");
// 5. Break dan continue
printf("Contoh break (berhenti di 5):\n");
for (int i = 1; i <= 10; i++) {
if (i == 5) {
break; // keluar loop saat i = 5
}
printf("%d ", i);
}
printf("\n\n");
printf("Contoh continue (lewati angka genap):\n");
for (int i = 1; i <= 10; i++) {
if (i % 2 == 0) {
continue; // skip angka genap
}
printf("%d ", i);
}
printf("\n");
// 6. Infinite loop (hati-hati!)
// while (1) {
// printf("Forever...\n");
// }
return 0;
}
8. Array
Array adalah kumpulan elemen dengan tipe data yang sama, disimpan dalam memori secara berurutan.
Cara deklarasi array:
tipe_data nama_array[ukuran];
tipe_data nama_array[] = {nilai1, nilai2, ...};
Indeks array dimulai dari 0.
Karakteristik array di C:
- Ukuran fixed (tidak bisa diubah setelah deklarasi)
- Semua elemen bertipe sama
- Alokasi memori berurutan
- Tidak ada bounds checking (hati-hati out of bounds!)
#include <stdio.h>
int main() {
// Deklarasi array dengan ukuran
int nilai[5]; // array 5 elemen (indeks 0-4)
// Mengisi array
nilai[0] = 80;
nilai[1] = 85;
nilai[2] = 90;
nilai[3] = 75;
nilai[4] = 95;
// Mengakses array
printf("Nilai pertama: %d\n", nilai[0]);
printf("Nilai ketiga: %d\n", nilai[2]);
// Looping array
printf("Semua nilai:\n");
for (int i = 0; i < 5; i++) {
printf("nilai[%d] = %d\n", i, nilai[i]);
}
// Inisialisasi langsung
int angka[] = {10, 20, 30, 40, 50, 60}; // ukuran otomatis 6
int size = sizeof(angka) / sizeof(angka[0]); // hitung jumlah elemen
printf("Array angka (%d elemen):\n", size);
for (int i = 0; i < size; i++) {
printf("%d ", angka[i]);
}
printf("\n\n");
// Array 2 dimensi (matriks)
int matrix[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
printf("Matrix 3x3:\n");
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
printf("%d ", matrix[i][j]);
}
printf("\n");
}
printf("\n");
// Array of characters (string)
char nama[] = "Budi";
printf("Nama: %s\n", nama);
// Manual string (dengan null terminator \0)
char kota[6] = {'J', 'a', 'k', 'a', 'r', '\0'};
printf("Kota: %s\n", kota);
// Mencari nilai maksimum
int data[] = {45, 78, 23, 89, 12, 67};
int n = sizeof(data) / sizeof(data[0]);
int max = data[0];
for (int i = 1; i < n; i++) {
if (data[i] > max) {
max = data[i];
}
}
printf("Nilai maksimum: %d\n", max);
return 0;
}
9. Functions
Fungsi adalah blok kode yang bisa dipanggil berulang kali.
Struktur fungsi:
return_type nama_fungsi(parameter1, parameter2) {
// body
return nilai; // jika return_type bukan void
}
Prototype fungsi:
Deklarasi fungsi sebelum digunakan (biasanya di atas main).
return_type nama_fungsi(parameter_types);
Parameter passing:
- Pass by value (default) - parameter di-copy
- Pass by reference (menggunakan pointer) - bisa mengubah nilai asli
#include <stdio.h>
// Function prototypes
int tambah(int a, int b);
double kali(double x, double y);
void sapa(char nama[]);
int faktorial(int n);
void swap(int *a, int *b); // pass by reference
int main() {
// Memanggil fungsi
int hasil = tambah(10, 20);
printf("10 + 20 = %d\n", hasil);
double product = kali(3.5, 2.0);
printf("3.5 * 2.0 = %.2lf\n", product);
sapa("Budi");
int f = faktorial(5);
printf("5! = %d\n", f);
// Pass by reference
int x = 10, y = 20;
printf("Sebelum swap: x=%d, y=%d\n", x, y);
swap(&x, &y); // kirim alamat (address)
printf("Setelah swap: x=%d, y=%d\n", x, y);
// Fungsi dengan array
int angka[] = {1, 2, 3, 4, 5};
int sum = sumArray(angka, 5);
printf("Sum array: %d\n", sum);
return 0;
}
// Definisi fungsi
int tambah(int a, int b) {
return a + b;
}
double kali(double x, double y) {
return x * y;
}
void sapa(char nama[]) {
printf("Halo, %s!\n", nama);
// void function tidak perlu return
}
// Fungsi rekursif
int faktorial(int n) {
if (n <= 1) {
return 1;
} else {
return n * faktorial(n - 1);
}
}
// Pass by reference (menggunakan pointer)
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
// Fungsi dengan array parameter
int sumArray(int arr[], int size) {
int total = 0;
for (int i = 0; i < size; i++) {
total += arr[i];
}
return total;
}
// Fungsi dengan static variable
int counter() {
static int count = 0; // static: nilai tetap antar pemanggilan
count++;
return count;
}
// Fungsi inline (saran ke compiler)
inline int kuadrat(int x) {
return x * x;
}
10. Pointer
Apa itu Pointer?
Pointer adalah variabel yang menyimpan alamat memori dari variabel lain. Ini adalah fitur paling powerful dan paling berbahaya di C.
Operator pointer:
&- address-of operator (mengambil alamat)*- dereference operator (mengakses nilai di alamat)
Deklarasi pointer:
int *ptr; // pointer ke integer char *cptr; // pointer ke char double *dptr; // pointer ke double
- Memanipulasi data secara langsung di memory
- Pass by reference ke fungsi
- Membuat struktur data dinamis (linked list, tree)
- Array dan string manipulation lebih efisien
#include <stdio.h>
int main() {
int x = 10;
int *ptr; // deklarasi pointer
ptr = &x; // ptr menyimpan alamat x
printf("Nilai x: %d\n", x);
printf("Alamat x: %p\n", &x);
printf("Nilai ptr (alamat yang disimpan): %p\n", ptr);
printf("Nilai yang ditunjuk ptr: %d\n", *ptr); // dereference
// Mengubah nilai melalui pointer
*ptr = 20;
printf("Setelah *ptr = 20, x menjadi: %d\n", x);
// Pointer ke pointer
int **ptr2 = &ptr;
printf("ptr2 (alamat ptr): %p\n", ptr2);
printf("**ptr2 = %d\n", **ptr2);
// Pointer dan array
int arr[] = {5, 10, 15, 20, 25};
int *arrPtr = arr; // nama array adalah pointer ke elemen pertama
printf("\nAkses array dengan pointer:\n");
for (int i = 0; i < 5; i++) {
printf("arr[%d] = %d, *(arrPtr + %d) = %d\n",
i, arr[i], i, *(arrPtr + i));
}
// Pointer arithmetic
printf("\nPointer arithmetic:\n");
printf("arrPtr = %p\n", arrPtr);
printf("arrPtr + 1 = %p (nilai: %d)\n", arrPtr + 1, *(arrPtr + 1));
printf("arrPtr + 2 = %p (nilai: %d)\n", arrPtr + 2, *(arrPtr + 2));
// Null pointer
int *nullPtr = NULL;
if (nullPtr == NULL) {
printf("\nnullPtr adalah NULL pointer\n");
}
// Jangan dereference null pointer!
// *nullPtr = 5; // ERROR! akan crash
return 0;
}
#include <stdio.h>
void doubleValue(int *x) {
*x = *x * 2; // mengubah nilai asli
}
int* createArray(int size) {
static int arr[100]; // static agar tidak hilang setelah fungsi selesai
for (int i = 0; i < size; i++) {
arr[i] = i * 10;
}
return arr; // return pointer ke array
}
// Fungsi dengan pointer ke pointer
void allocateMemory(int **ptr, int size) {
*ptr = (int*)malloc(size * sizeof(int)); // alokasi memory dinamis
for (int i = 0; i < size; i++) {
(*ptr)[i] = i * 5;
}
}
// Function pointer
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int main() {
int num = 10;
printf("Sebelum: %d\n", num);
doubleValue(&num);
printf("Setelah doubleValue: %d\n", num);
// Pointer ke array
int *arr = createArray(5);
printf("Array dari fungsi:\n");
for (int i = 0; i < 5; i++) {
printf("%d ", arr[i]);
}
printf("\n");
// Dynamic allocation
int *dynamicArr;
allocateMemory(&dynamicArr, 5);
printf("Dynamic array:\n");
for (int i = 0; i < 5; i++) {
printf("%d ", dynamicArr[i]);
}
printf("\n");
free(dynamicArr); // jangan lupa free!
// Function pointer
int (*op)(int, int); // deklarasi function pointer
op = add;
printf("add(5,3) = %d\n", op(5, 3));
op = subtract;
printf("subtract(5,3) = %d\n", op(5, 3));
return 0;
}
- Dangling pointer - pointer ke memory yang sudah dibebaskan
- Memory leak - lupa free memory yang dialokasikan
- Buffer overflow - menulis melebihi alokasi
- Null pointer dereference - akses NULL akan crash
11. String
Di C, string adalah array of characters yang diakhiri dengan null terminator (\0).
Deklarasi string:
char str1[] = "Hello"; // array, bisa diubah char *str2 = "World"; // string literal (read-only) char str3[20] = "C Programming"; // dengan ukuran tertentu
String functions (dari <string.h>):
strlen(s)- panjang stringstrcpy(dest, src)- copy stringstrcat(dest, src)- concatenatestrcmp(s1, s2)- compare (0 jika sama)strchr(s, c)- mencari karakterstrstr(s, sub)- mencari substring
#include <stdio.h>
#include <string.h>
int main() {
// Berbagai cara deklarasi string
char str1[] = "Hello";
char str2[20] = "World";
char *str3 = "C Programming";
printf("str1: %s\n", str1);
printf("str2: %s\n", str2);
printf("str3: %s\n", str3);
// String functions
char dest[50];
strcpy(dest, str1); // copy str1 ke dest
printf("strcpy: %s\n", dest);
strcat(dest, " "); // tambah spasi
strcat(dest, str2); // gabung str2
printf("strcat: %s\n", dest);
printf("Panjang dest: %lu\n", strlen(dest));
// String comparison
if (strcmp(str1, "Hello") == 0) {
printf("str1 sama dengan 'Hello'\n");
}
// Mencari karakter
char *pos = strchr(dest, 'o');
if (pos != NULL) {
printf("Karakter 'o' ditemukan di posisi: %ld\n", pos - dest);
}
// Mencari substring
char *sub = strstr(dest, "World");
if (sub != NULL) {
printf("'World' ditemukan: %s\n", sub);
}
// Manual string processing
char text[] = "Hello, C Language";
printf("\nManual processing:\n");
for (int i = 0; text[i] != '\0'; i++) {
printf("text[%d] = '%c' (ASCII: %d)\n", i, text[i], text[i]);
}
// Input string
char input[100];
printf("\nMasukkan nama: ");
fgets(input, sizeof(input), stdin); // aman, batasi input
input[strcspn(input, "\n")] = 0; // hapus newline
printf("Halo, %s!\n", input);
// Array of strings
char *names[] = {"Alice", "Bob", "Charlie", "David"};
int count = 4;
printf("\nDaftar nama:\n");
for (int i = 0; i < count; i++) {
printf("%d. %s\n", i + 1, names[i]);
}
return 0;
}
12. Struct & Union
Struct (Structure)
Struct mengelompokkan variabel dengan tipe berbeda dalam satu kesatuan.
Deklarasi struct:
struct NamaStruct {
tipe1 field1;
tipe2 field2;
// ...
};
Union
Union mirip struct, tapi semua field berbagi lokasi memory yang sama. Ukuran union = ukuran field terbesar.
Perbedaan struct vs union:
- Struct: setiap field punya memory sendiri
- Union: semua field berbagi memory yang sama
typedef untuk membuat alias, sehingga tidak perlu menulis struct setiap kali.
#include <stdio.h>
#include <string.h>
// Definisi struct
struct Mahasiswa {
char nama[50];
int umur;
float ipk;
char jurusan[30];
};
// Dengan typedef
typedef struct {
char merk[50];
int tahun;
int harga;
} Mobil;
// Nested struct
struct Alamat {
char jalan[100];
char kota[50];
int kodePos;
};
struct Pegawai {
char nama[50];
struct Alamat alamat;
float gaji;
};
// Union
union Data {
int i;
float f;
char str[20];
};
// Fungsi untuk menampilkan struct
void displayMahasiswa(struct Mahasiswa m) {
printf("Nama: %s\n", m.nama);
printf("Umur: %d\n", m.umur);
printf("IPK: %.2f\n", m.ipk);
printf("Jurusan: %s\n", m.jurusan);
printf("---\n");
}
int main() {
// Inisialisasi struct
struct Mahasiswa mhs1;
strcpy(mhs1.nama, "Budi Santoso");
mhs1.umur = 20;
mhs1.ipk = 3.75;
strcpy(mhs1.jurusan, "Informatika");
// Inisialisasi langsung
struct Mahasiswa mhs2 = {
"Ani Wijaya",
21,
3.90,
"Sistem Informasi"
};
printf("Data Mahasiswa 1:\n");
displayMahasiswa(mhs1);
printf("Data Mahasiswa 2:\n");
displayMahasiswa(mhs2);
// Menggunakan typedef (tanpa struct keyword)
Mobil mobil1 = {"Toyota", 2020, 250000000};
printf("Mobil: %s %d, Harga: Rp%d\n",
mobil1.merk, mobil1.tahun, mobil1.harga);
// Nested struct
struct Pegawai pgw1;
strcpy(pgw1.nama, "Joko");
strcpy(pgw1.alamat.jalan, "Jl. Merdeka No. 1");
strcpy(pgw1.alamat.kota, "Jakarta");
pgw1.alamat.kodePos = 12345;
pgw1.gaji = 5000000;
printf("\nData Pegawai:\n");
printf("Nama: %s\n", pgw1.nama);
printf("Alamat: %s, %s %d\n",
pgw1.alamat.jalan, pgw1.alamat.kota, pgw1.alamat.kodePos);
// Array of struct
struct Mahasiswa kelas[3] = {
{"Budi", 20, 3.5, "Informatika"},
{"Ani", 21, 3.8, "Sistem Informasi"},
{"Citra", 19, 3.9, "Teknik Komputer"}
};
printf("\nDaftar Kelas:\n");
for (int i = 0; i < 3; i++) {
printf("%d. %s - %s (IPK: %.2f)\n",
i+1, kelas[i].nama, kelas[i].jurusan, kelas[i].ipk);
}
// Pointer ke struct
struct Mahasiswa *ptr = &mhs1;
printf("\nAkses via pointer: %s, umur %d\n",
ptr->nama, ptr->umur); // menggunakan operator ->
// UNION
printf("\n=== DEMO UNION ===\n");
union Data data;
data.i = 10;
printf("data.i = %d\n", data.i);
data.f = 220.5;
printf("data.f = %.2f (i sekarang: %d, ter-overwrite)\n", data.f, data.i);
strcpy(data.str, "Hello");
printf("data.str = %s (i: %d, f: %.2f - semua berubah)\n",
data.str, data.i, data.f);
// Ukuran struct vs union
printf("\nUkuran struct Mahasiswa: %lu bytes\n", sizeof(struct Mahasiswa));
printf("Ukuran union Data: %lu bytes\n", sizeof(union Data));
// Struct bit field (untuk efisiensi)
struct {
unsigned int aktif : 1; // 1 bit
unsigned int role : 3; // 3 bits (0-7)
unsigned int umur : 8; // 8 bits (0-255)
} status;
status.aktif = 1;
status.role = 5;
status.umur = 25;
printf("\nBit fields: aktif=%d, role=%d, umur=%d\n",
status.aktif, status.role, status.umur);
printf("Ukuran bit field struct: %lu bytes\n", sizeof(status));
return 0;
}