Pemrograman · Bahasa pemrograman
Tutorial pemrograman C untuk pemula
Jawaban singkat
C adalah bahasa terkompilasi yang kecil dan cepat, dengan akses langsung ke memori lewat pointer. Tulis main di file .c, kompilasi dengan gcc hello.c -o hello, lalu jalankan ./hello. Konsep intinya: tipe berukuran tetap, fungsi, array dan string yang diakhiri null, pointer dan alamat, manajemen memori manual dengan malloc dan free, serta penanganan error lewat nilai kembalian.
Apa itu C dan untuk apa dipakai
C dibuat oleh Dennis Ritchie di Bell Labs pada awal 1970-an untuk menulis sistem operasi Unix. C distandarkan oleh ISO (C99, C11, C17, dan C23 adalah edisi utamanya). C dikompilasi menjadi kode mesin dengan runtime yang sangat kecil, sehingga berjalan hampir di mana saja. C dipakai untuk kernel sistem operasi (Linux), firmware embedded, database (SQLite), runtime bahasa (CPython ditulis dalam C), dan pustaka berperforma tinggi. Belajar C juga mengajarkan bagaimana memori dan komputer benar-benar bekerja.
Instal compiler dan jalankan Hello, world
Di Linux, instal gcc (misalnya sudo apt install build-essential); di macOS jalankan xcode-select --install untuk mendapatkan clang (juga tersedia sebagai gcc); di Windows gunakan MSYS2, WSL, atau Visual Studio.
#include <stdio.h>
int main(void) {
printf("Hello, world\n");
return 0;
}gcc -Wall -Wextra -std=c17 hello.c -o hello
./hello
# Hello, world#include memasukkan deklarasi dari file header, di sini pustaka input dan output standar. Mengembalikan 0 dari main berarti sukses. Selalu kompilasi dengan peringatan aktif (-Wall -Wextra).
Variabel dan tipe data dasar
Setiap variabel punya tipe yang menentukan ukuran dan maknanya. Ukuran bergantung pada platform, kecuali standar menyatakan lain; <stdint.h> menyediakan tipe berlebar pasti seperti int32_t.
| Tipe | Ukuran umum | Contoh | Format printf |
|---|---|---|---|
char | 1 byte | char c = 'A'; | %c |
int | 4 byte | int n = 42; | %d |
long long | 8 byte | long long big = 1LL << 40; | %lld |
double | 8 byte | double x = 3.14; | %f |
bool | 1 byte | bool ok = true; (C99 <stdbool.h>) | %d |
size_t | 8 byte pada 64-bit | size_t len = sizeof(arr); | %zu |
#include <stdio.h>
int main(void) {
int count = 7;
double avg = count / 2; /* 3.0: integer division first */
double avg2 = count / 2.0; /* 3.5 */
printf("%d %.1f %.1f\n", count, avg, avg2); /* 7 3.0 3.5 */
printf("%zu\n", sizeof(int)); /* 4 on most systems */
return 0;
}Alur kontrol dan fungsi
Fungsi harus dideklarasikan sebelum dipakai. Argumen dikirim secara by value: fungsi menerima salinan.
#include <stdio.h>
int square(int x) {
return x * x;
}
int main(void) {
int score = 72;
if (score >= 90) {
printf("A\n");
} else if (score >= 70) {
printf("B\n"); /* B */
} else {
printf("C\n");
}
for (int i = 0; i < 3; i++) {
printf("%d ", square(i)); /* 0 1 4 */
}
printf("\n");
int n = 10;
while (n > 1) n /= 2;
printf("%d\n", n); /* 1 */
return 0;
}C juga punya do/while, switch dengan label case (ingat break), dan goto, yang sebagian besar dipakai untuk pembersihan di jalur error.
Array dan string
Array adalah sejumlah elemen tetap yang disimpan berdampingan. C tidak memeriksa batas dan tidak menyimpan panjang, jadi Anda mengirim panjang secara terpisah. String adalah array char yang diakhiri byte nol '\0'.
#include <stdio.h>
#include <string.h>
int sum(const int *values, size_t n) {
int total = 0;
for (size_t i = 0; i < n; i++) total += values[i];
return total;
}
int main(void) {
int nums[] = {3, 1, 2, 5};
size_t n = sizeof nums / sizeof nums[0];
printf("%zu items, sum %d\n", n, sum(nums, n)); /* 4 items, sum 11 */
char name[16] = "Ada";
strncat(name, " Lovelace", sizeof name - strlen(name) - 1);
printf("%s (%zu chars)\n", name, strlen(name)); /* Ada Lovelace (12 chars) */
return 0;
}Ketika array dikirim ke fungsi, ia berubah (decay) menjadi pointer ke elemen pertamanya, itulah sebabnya sum menerima const int * dan sebuah panjang.
Fitur khas: pointer
Pointer menyimpan alamat memori dari nilai lain. &x memberi alamat x, dan *p membaca atau menulis nilai di alamat p. Pointer memungkinkan fungsi mengubah variabel milik pemanggil, berbagi data besar tanpa menyalin, dan membangun struktur data berantai.
#include <stdio.h>
void swap(int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
int main(void) {
int x = 1, y = 2;
int *p = &x;
*p = 10; /* changes x */
swap(&x, &y);
printf("x=%d y=%d\n", x, y); /* x=2 y=10 */
int arr[3] = {7, 8, 9};
int *q = arr;
printf("%d %d\n", *(q + 1), q[2]); /* 8 9: pointer arithmetic */
return 0;
}Memori dinamis dengan malloc dan free
Variabel lokal berada di stack dan hilang saat fungsi selesai. Untuk data yang ukurannya baru diketahui saat runtime, atau yang harus hidup lebih lama dari fungsi, alokasikan di heap dengan malloc dan lepaskan dengan free. Setiap malloc yang berhasil membutuhkan tepat satu free.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
size_t n = 5;
int *squares = malloc(n * sizeof *squares);
if (squares == NULL) {
fprintf(stderr, "out of memory\n");
return 1;
}
for (size_t i = 0; i < n; i++) squares[i] = (int)(i * i);
printf("%d\n", squares[4]); /* 16 */
free(squares);
squares = NULL; /* avoid using a dangling pointer */
return 0;
}Fungsi terkait adalah calloc (mengalokasikan dan mengisi nol) dan realloc (mengubah ukuran). Kelompokkan nilai yang berkaitan dengan struct, misalnya struct point { int x; int y; };.
Penanganan error
C tidak punya exception. Fungsi melaporkan error lewat nilai kembalian (sering -1, NULL, atau kode status), dan banyak fungsi pustaka juga mengatur errno global. Periksa setiap nilai kembalian yang bisa gagal.
#include <errno.h>
#include <stdio.h>
#include <string.h>
int main(void) {
FILE *f = fopen("missing.txt", "r");
if (f == NULL) {
fprintf(stderr, "cannot open: %s\n", strerror(errno));
return 1; /* cannot open: No such file or directory */
}
fclose(f);
return 0;
}Program kecil yang lengkap: penghitung baris dan kata
Program ini bekerja seperti wc mini: membaca file yang disebut di baris perintah dan mencetak jumlah baris, kata, dan byte.
#include <ctype.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "usage: %s FILE\n", argv[0]);
return 1;
}
FILE *f = fopen(argv[1], "r");
if (f == NULL) {
perror(argv[1]);
return 1;
}
long lines = 0, words = 0, bytes = 0;
int c, in_word = 0;
while ((c = fgetc(f)) != EOF) {
bytes++;
if (c == '\n') lines++;
if (isspace(c)) {
in_word = 0;
} else if (!in_word) {
in_word = 1;
words++;
}
}
fclose(f);
printf("%ld lines, %ld words, %ld bytes\n", lines, words, bytes);
return 0;
}Kompilasi dengan gcc -Wall -Wextra wc.c -o wc dan jalankan ./wc notes.txt. Perhatikan bahwa c bertipe int, bukan char, sehingga bisa menampung nilai khusus EOF.
Kesalahan umum pemula
- Memakai
=alih-alih==dalam kondisi. Peringatan (-Wall) menangkap sebagian besar kasus. - Lupa menyisakan ruang untuk
'\0'penutup saat menentukan ukuran buffer string. - Memakai
getsatauscanf("%s", buf)tanpa batas. Gunakanfgets(buf, sizeof buf, stdin). - Mengembalikan pointer ke variabel lokal, yang sudah tidak ada setelah fungsi selesai.
- Format
printftidak cocok dengan tipenya, seperti%duntuksize_t.
Langkah selanjutnya
Gunakan bagian C di cppreference.com sebagai referensi bahasa dan pustaka standar, dan baca halaman working group ISO (WG14) untuk standar itu sendiri. Berlatihlah dengan struct, linked list, file header, dan program multi-file yang dibangun dengan make. Debugger (gdb atau lldb) serta Valgrind atau AddressSanitizer akan menghemat berjam-jam. Setelah itu jelajahi C++ atau Rust, yang membangun di atas ide yang sama dengan keamanan lebih baik.
FAQ
Apakah C masih layak dipelajari?
Ya. C masih dipakai untuk sistem operasi, perangkat embedded, dan pustaka yang kritis terhadap performa, dan ia mengajarkan memori, pointer, serta cara kode terkompilasi berjalan, yang membantu di bahasa lain.
Apa perbedaan C dan C++?
C++ berawal sebagai ekstensi C dan menambahkan class, template, reference, exception, dan pustaka standar yang besar. C tetap kecil dan prosedural. Sebagian besar kode C hampir valid sebagai C++, tetapi keduanya standar yang terpisah.
Mengapa program C saya crash dengan segmentation fault?
Program mengakses memori yang bukan miliknya, biasanya lewat pointer null, belum diinisialisasi, atau sudah di-free, atau dengan mengindeks melewati akhir array. Jalankan di debugger atau dengan AddressSanitizer untuk menemukan barisnya.
Standar C mana yang sebaiknya dipakai?
C17 didukung luas oleh compiler terkini, dan C23 adalah standar terbaru. Tentukan versinya secara eksplisit, misalnya -std=c17, agar perilakunya konsisten.