Category Archives: Pemrograman

Berpindah ke Python untuk Software Numerik

Ketika saya baru pertama kali belajar tentang dunia programming, saya lebih suka membuat aplikasi dengan menggunakan bahasa pemrograman PHP (PHP Hypertext Preprocessor) dengan basis web. Dulu beberapa teman yang minta dibuatkan aplikasi web, baik itu blog, aplikasi database, atau aplikasi perhitungan sederhana, biasanya saya membuatkannya dalam bentuk web dengan menggunakan PHP karena memang fungsinya diperuntukkan untuk aplikasi web.

Akhir-akhir ini, saya sering ingin membuatkan sebuah aplikasi perhitungan yang tidak membutuhkan database. Aplikasi ini khusus untuk ranah teknik sipil (engineering) dan tidak memerlukan koneksi database seperti MySQL atau PostgreSQL. Saya sempat berpindah ke pemrograman desktop selama masih di Laboratorium Rekayasa Struktur. Saat itu saya menggunakan bahasa C# untuk membuat aplikasi  Analisis Kurvatur Momen.

Di awal tahun ini, setelah keluar dari lab, saya membuat sebuah software analisis struktur, openSAP32, yang saya buat dengan menggunakan Python. Karena kesibukan pekerjaan di luar Jakarta dan saat ini saya sedang bertugas ke site di Lhokseumawe, software ini sedikit terlantar. Sedikit informasi mengenai software ini, saya berencana membuat software analisis struktur sederhana yang bisa saya pakai tanpa harus menggunakan software komersial. Tujuannya adalah mempelajari lebih dalam tentang analisis struktur metode matriks dan berharap bisa meningkatkan nalar berpikir, syukur kalau ternyata nanti bisa dikembangkan hingga analisis gempa dan dinamik. Untuk saat ini, software ini baru bisa digunakan untuk analisis rangka batang 2 dimensi, dengan fitur yang masih minim. Kalau ada waktu luang, saya terus berusaha mengembangkan sofware ini.

Ketika banyak tenaga dan pikiran yang harus dibutuhkan untuk membuat openSAP32, saya terpikir untuk membuat software yang lebih sederhana, yang bisa saya selesaikan dalam waktu singkat. Nantinya aplikasi ini saya kumpulkan menjadi sebuah tools yang berguna buat saya sendiri dan juga engineer sipil lainnya tentunya. Untuk kasus ini, saya berpikir bahwa aplikasi desktop bukanlah pilihan yang tepat. Saya melihat aplikasi desktop lebih ditujukan pada sebuah aplikasi yang besar yang fungsinya untuk sebuah tugas khusus, sama seperti openSAP32.

Kumpulan aplikasi ini lebih cocok dibuat di atas platform web yang menangani aplikasi yang lebih kecil. Model MVC (Mode-View-Controller) pun cocok digunakan untuk aplikasi numerik. Yang berbeda adalah, jika umumnya pada aplikasi database, model digunakan sebagai media query data ke database, pada aplikasi numerik, namun model digunakan sebagai tempat mengolah data berupa perhitungan numerik yang diharapkan akan ditampilkan hasilnya.

Sudah hampir sebulan ini saya mencoba mempelajari pemrograman web dengan menggunakan python. Saya lebih memilih menggunakan python karena selain bisa digunakan untuk web, banyak library python yang khusus dibuat untuk proses numerik. Contoh library tersebut adalah Numpy, Scipy, Matplotlib, dan Simpy. Semuanya saya rasa sudah cukup matang sebagai sebuah library.

Ada banyak pilihan framework pada python. Di antara Flask, CherryPy, Bottle, Tornado, Django, dan web2py, saya menjatuhkan pilihan pada CherryPy. Flask bagus, hanya saja dukungan untuk Python 3 masih tanda tanya. Tornado khusus digunakan untuk web server untuk proses asynchronous, sedangkan saya tidak membutuhkannya. Bottle hanya menyediakan web server HTTP yang tidak production-ready. Django terlalu besar untuk aplikasi yang saya buat dan web2py sepertinya terlalu kompleks. CherryPy saya pilih karena tidak dilengkapi oleh 3rd-party yang memang tidak saya butuhkan seperti akses database dan autentikasi. Aplikasi yang ingin saya buat murni interaksi dinamik antara user dan kode yang bermain di level numerik. CherryPy juga sudah dilengkapi built-in http server sehingga tidak membutuhkan banyak dependencies.

Awalnya saya cukup kesulitan mempelajari framework ini. Ditambah lagi saya harus mempelajari Mako sebagai library untuk template aplikasi ini nantinya. Untuk membuat framework ini bekerja sebagai arsitektur MVC, saya harus membuat beberapa script agar bisa berjalan sesuai dengan keinginan.  Semuanya berada dalam kontrol kita, tidak seperti banyak framework PHP yang semuanya tinggal pakai karena memang dari awal sudah menggunakan konsep MVC. Bahkan model routing dan dispatching pun bebas mau yang seperti apa.

Akhirnya saya bisa sedikit puas karena berhasil membuat dasar dari model aplikasi yang saya inginkan. Begitulah saya yang pada awalnya berharap bisa menguasai framework ini dengan cepat, ternyata harus bersabar lebih lama untuk mendapatkan apa yang saya harapkan. Tampaknya beralih ke Python adalah langkah yang menurut saya akan sangat berguna ke depannya 🙂

Kalau kamu ingin melihat kerangka MVC aplikasi saya, kamu bisa melihat-lihat ke halaman github aplikasi yang saya beri nama civil-engineering-toolbox.

Filter Baris pada Table dengan jQuery

Pada konferensi CECAR 6 (6th Civil Engineering Conference in Asia Region) yang dilaksanakan Agustus kemaren, saya ikut membantu membuat sebuah aplikasi berbasis web yang digunakan untuk menampilkan daftar dan isi proceeding konferensi tersebut. Saya membuat daftar judul proceeding dengan menggunakan tabel, mirip dengan aplikasi pengolah spreadsheet, tapi kali ini ditampilkan di web.

Agar fungsi aplikasi ini bisa maksimal, saya perlu menambahkan fungsi filter yang membatasi daftar judul berdasarkan hasil pencarian atau kategori judul proceeding. Oleh karena itu, saya membuat sebuah elemen input sebagai search box dan sebuah elemen html select yang memuat daftar kategori. Saya menginginkan agar fungsi filter ini bisa digunakan secara realtime atau hasilnya langsung bisa ditampilkan begitu ada perubahan pada inputan filter tersebut. Untuk mempermudah, saya menggunakan library javascript jQuery agar proses development bisa berjalan lebih cepat.

Tabel saya beri id #table_paper, elemen input search box saya beri id #search, dan input seleksi kategori saya beri id #category.

<!-- Elemen HTML untuk filter -->
<input type="text" name="search" id="search">
<select id="category">
	<option value="all">All</option>
	<option value="key">Keynote</option>
	<option value="short">Short Course</option>
	<option value="cat1">Advanced Construction Technologies</option>
	<option value="cat2">Analytical and Design Methods</option>
	...
</select>
 
<!-- Tabel -->
<table class="table table-bordered table-hover tablesorter" id="table_paper">
	<thead>
	<tr>
		<td><strong>PAPER ID</strong></td>
		<td><strong>TITLE</strong></td>
		<td><strong>AUTHORS</strong></td>
		<td><strong>COUNTRY</strong></td>
		<td><strong>DOWNLOAD</strong></td>
	</tr>
	</thead>
	<tbody>
	<tr class="cat11 all">
		<td class="idpaper">16</td>
		<td class="title">FOOTING REINFORCEMENT METHOD BY STEEL SHEET PILES WITH CLOSED SECTIONS</td>
		<td class="author">Hiroaki Nakayama, Noriyoshi Harata, and Atsushi Kato</td>
		<td class="country">Japan</td>
		<td class="pdf"><a href="file/proceeding/Paper 016.pdf">PDF</a></td>
	</tr>
	<tr class="cat7 all">
		<td class="idpaper">17</td>
		<td class="title">RISK FACTOR IDENTIFICATION IN THE MANUFACTURING PROCESS OF HOLLOW CORE SLAB</td>
		<td class="author">Theresita Herni Setiawan, and Ihzarmurafi Huza Sukarni</td>
		<td class="country">Indonesia</td>
		<td class="pdf"><a href="file/proceeding/Paper 017.pdf">PDF</a></td>
	</tr>
	...
	</tbody>
</table>

Fungsi javascript untuk filter diberikan pada kode di bawah ini. Baris 2-5 adalah fungsi tambahan agar filter bersifat case-insensitive (huruf besar/kecil akan memberikan hasil yang sama).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$(document).ready(function(){
	jQuery.expr[':'].contains = function(a, i, m) {
		return jQuery(a).text().toUpperCase()
			.indexOf(m[3].toUpperCase()) >= 0;
	};
 
	var all_content = $("#table_paper").parent().html();
	// Detect events
	$("#search").keyup(function(){
		filter(all_content);
	});
	$('#category').change(function(){
		filter(all_content);
	});
});
 
// Search Function
function filter(all_content){
	$("#table_paper").parent().html(all_content);
	var s = $("#search").val();
	var kat = $("#category").val();
	$("#table_paper tbody tr:not(:contains('" + s + "'))").hide();
	$("#table_paper tbody tr:not([class~='" + kat + "']) ").each(function(){
		$(this).hide();
	});
}

Menampilkan Referensi dari Bibtex External pada Latex

Beberapa bulan ini saya menggunakan Latex untuk membuat sebuah dokumentasi. Ternyata pemakaiannya susah-susah-gampang. Banyak yang harus dipelajari sebelum bisa menggunakan Latex dengan lancar. Learning curve nya sangat berbeda jika dibandingkan dengan menggunakan software word processing berbasis WYSIWYG (What You See Is What You Get) seperti Microsoft Word atau Libreoffice Writer.

Salah satu fitur Latex adalah dukungan terhadap format referensi Bibtex, yaitu manajemen sumber referensi pada dokumen yang hendak dibuat. Dengan Bibtex, pengguna dengan mudah melakukan pengutipan (cite) terhadap sebuah artikel, buku, jurnal, atau sumber referensi lainnya. Kelebihan Bibtex lainnya adalah file Bibtex bisa dipisah dengan dokumen utama, sehingga file Bibtex ini bisa dipakai untuk dokumen lainnya. Pada dokumen utama, referensi akan ditandai dengan nomor atau nama depan pengarang, tergantung pengaturan yang kita buat.

Ketika saya ingin mengutip sebuah sumber, masalah yang muncul adalah dokumen Latex tidak menampilkan referensi melainkan tanda tanya. Ini artinya dokumen latex belum mengenali sumber referensi pada file Bibtex. Setelah saya selidiki dengan membuka beberapa sumber, saya menemukan sebuah artikel yang menginformasikan bahwa dibutuhkan trik untuk menampilkan nomor referensi pada dokumen.

Urutan yang harus dilakukan agar referensi ditampilkan pada dokumen latex diberikan dalam langkah-langkah berikut:

  1. latex latex_source_code.tex
  2. bibtex latex_source_code.aux
  3. latex latex_source_code.tex
  4. latex latex_source_code.tex

Langkah pertama akan menghasilkan error seperti di bawah ini:

LaTeX Warning: Citation `lamport94' on page 1 undefined on input line 21.
...
LaTeX Warning: There were undefined references.

Langkah kedua digunakan untuk mendefinisikan semua referensi yang dipakai dalam dokumen tersebut.

This is BibTeX, Version 0.99c (Web2C 7.3.1)
The top-level auxiliary file: latex_source_code.aux
The style file: plain.bst
Database file #1: sample.bib

Langkah ketiga adalah menjalankan Latex untuk kedua kalinya. Error yang muncul adalah “LaTeX Warning: Label(s) may have changed. Rerun to get cross-references right“. Perintah ini dengan jelas menyuruh kita untuk menjalankan latex sekali lagi (langkah ke-4) untuk menampilkan referensi pada dokumen kerja. Jadi kita tidak perlu berurusan dengan file Bibtex itu sendiri (format *.bib).

Untuk informasi tentang manajemen bibliografi, bisa merujuk ke sumber ini: http://en.wikibooks.org/wiki/LaTeX/Bibliography_Management

URL Dinamik untuk Framework Laravel dan Code Igniter

Framework PHP Laravel dan Code Igniter menggunakan URL aplikasi yang didefinisikan pada file konfigurasi masing-masing framework. Konfigurasi alamat aplikasi ini akan dipakai oleh framework untuk menghasilkan alamat URL seperti pada form, link, dan kebutuhan framwork lainnya.

Pada framework Laravel, konfigurasi ini bisa dilihat pada file app/config/app.php dengan baris kode seperti di bawah ini

'url' => 'http://localhost',

sedangkan pada framework Code Igniter, konfigurasi bisa dilihat pada file application/config/config.php dengan baris kode seperti di bawah

$config['base_url']	= 'http://localhost/';

Aplikasi umumnya didevelop di komputer dengan URL localhost dan akan dipindahkan ke hosting yang berbeda URL nya dengan komputer pada saat developing. Ketika memindahkan aplikasi ke web server, terpaksa kita harus mengganti alamat URL. Jika mengganti secara manual, akan sangat merepotkan terutama jika sering memindah-mindahkan file. Dengan variabel spesial PHP, alamat URL bisa diganti agar lebih dinamis menyesuaikan dengan alamat URL aplikasi.

Untuk Laravel, potongan kode di atas bisa diganti menjadi

'url' => 'http://'.$_SERVER['SERVER_NAME'],

sedangkan untuk Code Igniter menggunakan konfigurasi di bawah ini

$config['base_url']	= 'http://'.$_SERVER['SERVER_NAME'];

Mengganti Vector 2 Dimensi dengan Menggunakan Referensi Pada Fungsi

Beberapa minggu yang lalu, saya kesulitan dalam melewatkan array 2D sebagari referensi dari satu fungsi ke fungsi lain. Di tengah-tengah kesulitan tersebut, saya menemukan sebuah tulisan yang mengatakan bahwa memang cukup sulit untuk melewatkan array 2 dimensi dengan menggunakan referensi alamat. Namun, kita tetap bisa melemparkan (return) sebuah referensi dari sebuah fungsi ke dalam sebuah pointer. Jadi sifatnya hanya 1 arah (return), tidak seperti referensi yang variabelnya akan berubah nilainya di dalam fungsi yang memanipulasinya.

Karena tidak puas, saya mencoba bermain-main dengan vector. Pada awalnya saya memang agak kesulitan, namun setelah dipelajari lebih mendalam, tidak sulit untuk mengontrol vector yang kita buat. Ternyata, vector ini bisa dilewatkan sebagai referensi ke dalam sebuah fungsi :D. Wow, saya cukup senang karena memang itu yang saya inginkan. Penggunaannya juga tidak jauh berbeda dengan melewatkan variabel pada umumnya. Sebagai contoh, di bawah ini adalah sebuah program untuk membuat sebuah vector 2 dimensi, lalu memanggil sebuah fungsi untuk memanipulasi vector tersebut, kemudian menampilkan isi vector yang sudah diganti tersebut.

#include <iostream>
#include <vector>
using namespace std;
 
void manipulasiVector(vector<vector<double> > &);
 
int main()
{
	typedef vector<double> vint;
	vint tmp(4);
	vector<vint> matriks(3);
	int i=0, j=0;
	cout << endl;
	for(i=0; i<3; i++){
		for(j=0; j<4; j++){
			tmp[j]=12*i+j;
			matriks[i]=tmp;
			cout << matriks[i][j] << " ";
		}
		cout << endl;
	}
	manipulasiVector(matriks);
	for(i=0; i<3; i++){
		for(j=0; j<4; j++){
			cout << matriks[i][j] << " ";
		}
		cout << endl;
	}
	return 0;
}
 
 
void manipulasiVector(vector<vector<double> > &v){
	int i=0,j=0;
	vector<double> tmp(10);
	for(i=0; i<3; i++){
		for(j=0; j<4; j++){
			tmp[j]= 8+i+j;
			v[i] = tmp;
		}
		cout << endl;
	}
}

Mengembalikan Pointer Array 2D dari Fungsi

Ketika kita membuat sebuah variabel yang diinisialisasi dengan pointer, variabel tersebut bisa dilewatkan ke dalam sebuah fungsi dan dikembalikan dalam bentuk alamat (pointer). Ketika berpindah-pindah dari satu fungsi ke fungsi lain, nilai pointer akan berubah secara dinamik (pass by address). Namun, saya mencoba membuat sebuah array 2D dan ingin melewatkan alamat pointer tersebut ke sebuah fungsi, yang nantinya fungsi tersebut akan mengganti isi array kemudian mengembalikan alamat pointer array tersebut. Sayang sekali banyak artikel yang mengatakan bahwa kita tidak bisa melewatkan pointer array 2D melalui fungsi yang telah didefinisikan.

Meskipun pointer array tidak bisa dilewatkan melalui fungsi, namun fungsi masih tetap bisa mengembalikan pointer array 2D. Jadi array 2D dibentuk di dalam fungsi, lalu alamatnya dikembalikan dan selanjutnya bisa dimasukkan ke dalam pointer lain.

Kode di bawah ini adalah cara yang saya temukan di internet. Mungkin ada cara lain, tapi saya belum mengetahuinya 🙂

#include <iostream>
using namespace std;
 
int** editArray();
int main(){
	int i=0, j=0;
	int **arr;
	arr=editArray();
	for(i=0; i<2; i++){
		for(j=0; j<4; j++){
			cout << arr[i][j] << " ";
		}
		cout << endl;
	}
	//system("pause");
}
 
int** editArray(){
	int** tmp;
	tmp = 0;
	tmp = new int*[100]; // 100 baris -> tmp [100][x];
	int i=0;
 
	/* Untuk kemudahan, 2 buah contoh cara memasukkan nilai pada variable
		pada array 'tmp' diberikan dalam 1 fungsi. 
		Silahkan berikan komentar pada baris-baris pada salah satu contoh
		agar 1 cara saja yang dipakai.
	*/
 
	/* Contoh 1: memasukkan nilai awal */
	for(i=0; i<2; i++){
		tmp[i] = new int[4];	// 4 kolom -> tmp[100][4]
		tmp[i][0] = (i+2)*1;
		tmp[i][1] = (i+2)*2;
		tmp[i][2] = (i+2)*3;
		tmp[i][3] = (i+2)*4;
	}
 
	/* Contoh 2: mengedit array */
	tmp[0] = new int[4];
	tmp[0][0]=2;
	tmp[0][1]=3;
	tmp[0][2]=4;
	tmp[0][3]=5;
 
	tmp[1] = new int[4];
	tmp[1][0]=20;
	tmp[1][1]=30;
	tmp[1][2]=40;
	tmp[1][3]=50;
 
    return tmp;
}

Melewatkan Fungsi sebagai Parameter Fungsi dalam C++

Bukan hanya variabel yang bisa dilewatkan pada sebuah fungsi dalam pemrograman C/C++. Fungsi juga bisa dilewatkan sebagai parameter. Konsepnya hampir sama saja, namun dengan sedikit tambahan syntax agar fungsi bisa dilewatkan dan berhasil dijalankan. Umumnya, pemanggilan fungsi dilakukan untuk menjalankan fungsi di dalam fungsi. Lebih jelasnya, ketika program memanggil sebuah fungsi, maka kita melewatkan sebuah fungsi sebagai parameter untuk kemudian dijalankan oleh fungsi pertama tadi.

Untuk bisa mendemonstrasikan contoh bagaimana melewatkan fungsi sebagai parameter, dibutuhkan paling tidak 2 fungsi selain fungsi utama (main). Dalam contoh di bawah ini, kita menggunakan 2 fungsi: trigger() dan sum(). Fungsi trigger() akan dipanggil di program utama. Fungsi sum() akan dilewatkan sebagai parameter fungsi trigger() untuk kemudian dijalankan di dalam fungsi trigger() itu sendiri.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
using namespace std;
 
int trigger(int (*)(int));
int sum(int end);
 
int main(){
	cout << trigger(&sum) << endl;
	return 0;
}
 
int trigger(int (*f)(int)){
	int end=50;
	return (*f)(end);
 
}
int sum(int end){
	int i, sum=0;
	for(i=0; i<end; i++){
		sum += i;
	}
	return sum;
}

Untuk melewatkan fungsi sebagai parameter, kita harus menuliskan tipe kembalian fungsi, lalu pointer yang menunjuk ke nama fungsi, dan tipe parameter fungsi.

4
int trigger(int (*)(int));

Bentuk int (*)(int) merupakan bentuk yang sama dengan nama fungsi yang akan dipanggil:

int sum(int end);

Untuk deklarasi fungsi tersebut, kita menggunakan pointer agar bisa memanggil fungsi yang dimaksud.

int trigger(int (*f)(int)){
	int end=50;
	return (*f)(end); // dalam kasus ini, artinya sama dengan -> return sum(end);
 
}

Untuk menggunakan fungsi trigger() dalam program utama, kita melewatkan referensi fungsi sum() di dalam parameter fungsi trigger.

trigger(&sum)

Bagaimana jika ingin melewatkan fungsi beserta dengan parameternya? Kita tinggal menambah parameter lain di dalam fungsi yang memanggil tadi. Pada kasus di atas, variabel end dideklarasikan di dalam fungsi trigger. Dalam contoh di bawah ini, variabel end akan dideklarasikan di dalam fungsi main dan akan dilewatkan dalam fungsi trigger.

#include <iostream>
using namespace std;
 
int trigger(int (*)(int), int);
int sum(int end);
 
int main(){
	int end = 50;
	cout << trigger(&sum, end) << endl;
	return 0;
}
 
int trigger(int (*f)(int), int end){
	return (*f)(end);	
}
int sum(int end){
	int i, sum=0;
	for(i=0; i<end; i++){
		sum += i;
	}
	return sum;
}

Secara teknis, kita tidak bisa melewatkan parameter bersamaan dengan nama fungsi yang dipanggil, contohnya:

trigger(&sum(4)); // tidak akan berhasil dicompile

Oleh karena itulah, parameter fungsi yang akan dilewatkan diberikan sebagai parameter tambahan seperti potongan kode di bawah ini.

int trigger(int (*f)(int), int end){
	return (*f)(end);	
}
trigger(&sum, 5);

Pointer dan Reference

Beberapa hari ini saya kembali belajar tentang bahasa pemrograman C++ namun dengan cakupan yang lebih luas dan mendalam. Dari dulu saya berusaha mencoba membaca source code C++ dalam proyek mini seseorang, namun tetap saja dengan pemahaman C++ yang pas-pasan malah membuat saya tidak betah berlama-lama dengan bahasa yang satu ini. Syukurlah dengan pembelajaran yang intensif saya sedikit bisa mengerti konsep dalam bahasa C++ yang sebelumnya tidak saya pahami.

Agar lebih konkrit, saya ingin membawakan sedikit pengetahuan yang saya peroleh mengenai pointer ke dalam sebuah artikel.

Dilihat dari datanya, sebuah variabel sebenarnya menyimpan 2 buah nilai: alamat variabel itu dan nilai variabel itu. Untuk bisa mengakses alamat ini, ada 2 cara yang bisa dipakai: menggunakan referensi atau menggunakan pointer.

Contoh di bawah ini adalah menggunakan referensi. Alamat variabel bisa diakses dengan menggunakan tanda & di depaan variabel yang ingin dilihat. Nilai x bisa berubah setiap saat namun alamatnya tidak akan berubah. Ibaratnya penghuni rumah mungkin akan berganti orang, namun sebuah rumah di sebuah perkampungan akan memiliki alamat yang tetap.

1
2
3
4
5
6
int x = 12;
cout << "Nilai:" << x << endl; //mengakses nilai x=12
cout << "Alamat:" << &x << endl; //mengakses alamat -> A
x = 14;
cout << "Nilai:" << x << endl; //mengakses nilai, x=14
cout << "Alamat:" << &x << endl; //mengakses alamat -> A (alamat tetap)

Potongan kode di bawah ini adalah cara untuk mendeklarasikan sebuah pointer p yang menunjuk ke variabel x. Ada 2 cara untuk mendeklarasikan pointer: pertama adalah dengan mendeklarasikan langsung pada saat inisialisasi (contoh pada baris 2) dan cara lain adalah mendeklarasikan kemudian (contoh baris 3).

1
2
3
4
5
6
7
int x = 12;  // inisialisasi variabel x=12
int *p = &x; // alamat dari x disimpan ke dalam pointer p
p = &x;  // alamat dari x disimpan ke dalam pointer p, fungsinya sama dengan baris 2
*p=13; // nilai berubah menjadi *p=13 dan x=13, namun alamat nya tetap, yaitu yang berasal dari x
 
int y = 15;  // deklarasi variabel y
p = &y;  // alamat pointer p berubah ke alamat y, nilai *p=15

Dalam potongan kode di atas, p adalah sebuah variabel yang menyimpan alamat saja. Memang itulah kegunaan pointer, yaitu menyimpan sebuah alamat, sedangkan nilainya bergantung dari nilai dari alamat yang disimpannya. Ibaratnya, sebuah buku kontak hanya bisa menyimpan alamat rumah saja, namun jika kita pergi ke alamat rumah tersebut, bisa saja penghuninya berbeda tergantung siapa yang memiliki rumah tersebut.