Oleh:
Iwan Syarif
Riyanto Sigit
Afrida Helen
Umi Sa’adah
Toru MUSO (JICA Expert)
Terima kasih kami sampaikan kepada berbagai pihak yang telah memberikan
kontribusi dalam penyelesaian buku ini, yaitu:
° Toru Muso, Longterm JICA Expert Program Studi Teknologi Informasi
° Ir. Elly Purwantini
° Dosen dan staf di Program Studi Teknologi Informasi
Tak ada gading yang tak retak, begitu kata pepatah. Demikian juga dengan kami,
sekalipun buku ini telah selesai melalui proses dan review yang cukup lama, namun masih
terbuka kemungkinan adanya beberapa kekurangan di dalamnya. Oleh karena itu, masukan,
kritik dan saran sangat kami harapkan untuk lebih menyempurnakan diktat ini pada
kesempatan mendatang.
Mudah-mudahan sedikit yang kami bisa sumbangkan ini, akan dicatat oleh Allah
SWT sebagai bagian dari amal sholeh kami dan akan menjadi ilmu yang bermanfaat, yang
senantiasa akan mengalirkan pahala bagi orang-orang yang mengajarkannya. Amin….
PENYUSUN
i
BAB I
SEKILAS TENTANG C
Tujuan :
1. Menjelaskan sejarah dan ruang lingkup pemakaian bahasa C
2. Menjelaskan kelebihan dan kekurangan bahasa C
3. Menjelaskan proses kompilasi dan linking program C
4. Menjelaskan struktur penulisan bahasa C dan menjelaskan komponen-komponen
program dalam contoh aplikasi sederhana
1
2
buah kata-kata kunci (keywords) standar. Versi-versi bahasa C yang menyediakan paling
tidak 32 kata-kata kunci ini dengan sintaks yang sesuai dengan yang ditentukan oleh standar,
maka dapat dikatakan mengikuti standar ANSI. Buku ajar ini didasarkan pada bahasa C dari
standar ANSI.
Pada saat ini C merupakan bahasa pemrograman yang sangat populer di dunia.
Banyak pemrograman yang dibuat dengan bahasa C seperti assembler, interpreter, program
paket, sistem operasi, editor, kompiler, program bantu, Word Star, Dbase, aplikasi untuk
bisnis, matematika, dan game, bahkan ada pula yang menerapkannya untuk kecerdasan
buatan.
Dalam beberapa literatur bahasa C digolongkan sebagai bahasa tingkat menengah.
Penggolongan ke dalam bahasa tingkat menengah bukanlah berarti bahwa bahasa C lebih
sulit dibandingkan dengan bahasa tingkat tinggi seperti PASCAL atau BASIC. Demikian
juga bahasa C bukanlah bahasa yang berorientasi pada mesin seperti bahasa mesin dan
assembly. Pada kenyataannya bahasa C mengkombinasikan elemen dalam bahasa tingkat
tinggi dan bahasa tingkat rendah. Kemudahan dalam membuat program yang ditawarkan
pada bahasa tingkat tinggi dan kecepatan eksekusi dari bahasa tingkat rendah merupakan
tujuan diwujudkannya bahasa C.
ke dalam bentuk program. Hal ini dikarenakan C merupakan bahasa yang berorientasi
pada permasalahan, bukan berorientasi pada mesin.
C memungkinkan memanipulasi data dalam bentuk bit maupun byte. Di samping itu juga
memungkinkan untuk memanipulasi alamat dari suatu data atau pointer.
Adapun kelemahan bahasa C yang dirasakan oleh para pemula bahasa C:
Banyaknya operator serta fleksibilitas penulisan program kadang-kadang
membingungkan pemakai. Kalau tidak dikuasai sudah tentu akan menimbulkan masalah.
Para pemrogram C tingkat pemula umumnya belum pernah mengenal pointer dan tidak
terbiasa menggunakannya. Padahal keampuhan C justru terletak pada pointer. Kesulitan
yang diuraikan di depan akan bersifat sementara saja. Kalau para pemula C mau
mempelajarinya, sebenarnya tak ada yang dikatakan sulit sekali mengenai C. Mereka
yang sudah terbiasa justru menyatakan bahwa bekerja dengan C sangat menyenangkan.
Pepatah mengatakan “Di mana ada kemauan di situ ada jalan” dan “Jika tak kenal maka
tak sayang”.
kompilernya. Keuntungannya, proses eksekusi dapat berjalan dengan cepat, sebab tak ada
lagi proses penerjemahan. Di samping itu, program sumber bisa dirahasiakan, sebab yang
dieksekusi adalah program yang sudah dalam bentuk kode mesin. Sedangkan
kelemahannya, proses pembuatan dan pengujian membutuhkan waktu relatif lebih lama,
sebab ada waktu untuk mengkompilasi (menerjemahkan) dan ada pula waktu melakukan
proses linking. Perlu pula diketahui, program akan berhasil dikompilasi hanya jika program
tak mengandung kesalahan secara kaidah sama sekali.
Proses dari bentuk program sumber C (source program, yaitu program yang ditulis
dalam bahasa C) hingga menjadi program yang executable (dapat dieksekusi secara
langsung) ditunjukkan pada Gambar 1.1 di bawah ini.
EDITOR EDITOR
KOMPILER
LINKER
FILE
EXECUTABLE
Keterangan Gambar :
5
bisa saja tidak mengandung pernyataan sama sekali. Walaupun fungsi tidak memiliki
pernyataan, kurung kurawal haruslah tetap ada. Sebab kurung kurawal mengisyaratkan awal
dan akhir definisi fungsi. Berikut ini adalah struktur dari program C
main()
{
statemen-statemen; fungsi utama
}
fungsi_fungsi_lain()
{
statemen-statemen; fungsi-fungsi lain yang }
ditulis oleh pemrogram
b. Fungsi printf().
Fungsi printf() merupakan fungsi yang umum dipakai untuk menampilkan suatu keluaran
pada layar peraga. Untuk menampilkan tulisan
Pernyataan di atas berupa pemanggilan fungsi printf() dengan argumen atau parameter
berupa string. Dalam C suatu konstanta string ditulis dengan diawali dan diakhiri tanda
petik-ganda (“). Perlu juga diketahui pernyataan dalam C selalu diakhiri dengan tanda
titik koma (;). Tanda titik koma dipakai sebagai tanda pemberhentian sebuah pernyataan
dan bukanlah sebagai pemisah antara dua pernyataan.
Tanda \ pada string yang dilewatkan sebagai argumen printf() mempunyai makna yang
khusus. Tanda ini bisa digunakan untuk menyatakan karakter khusus seperti karakter
baris-baru ataupun karakter backslash (miring kiri). Jadi karakter seperti \n sebenarnya
menyatakan sebuah karakter. Contoh karakter yang ditulis dengan diawali tanda \ adalah:
dengan string kontrol dapat berupa satu atau sejumlah karakter yang akan ditampilkan
ataupun berupa penentu format yang akan mengatur penampilan dari argumen yang
terletak pada daftar argumen. Mengenai penentu format di antaranya berupa:
Contoh:
#include <stdio.h>
main(
) {
printf(“No : %d\n”, 10);
printf(“Nama : %s\n”, “Ali”);
printf(“Nilai : %f\n”,80.5);
printf(“Huruf : %c\n”,‘A’); }
#include “namafile”
#include <stdio.h>
main()
{
printf(“Coba\n”); //Ini adl program pertama }
Kesimpulan :
• Akar dari bahasa C adalah bahasa BCPL yang dikembangkan oleh Martin Richards
pada tahun 1967.
• Bahasa C pertama kali digunakan pada komputer Digital Equipment Corporation
PDP-11 yang menggunakan sistem operasi UNIX.
• C adalah bahasa yang standar, artinya suatu program yang ditulis dengan versi bahasa
C tertentu akan dapat dikompilasi dengan versi bahasa C yang lain dengan sedikit
modifikasi. Standar bahasa C yang asli adalah standar dari UNIX.
• Interpreter adalah suatu jenis penerjemah yang menerjemahkan baris per baris
intsruksi untuk setiap saat, sedangkan kompiler merupakan jenis penerjemah cara
kerjanya adalah menerjemahkan seluruh instruksi dalam program sekaligus.
• Program C pada hakekatnya tersusun atas sejumlah blok fungsi.
• Fungsi main() merupakan fungsi istimewa yang harus ada pada program, sebab fungsi
inilah yang menjadi titik awal dan titik akhir eksekusi program.
• Fungsi printf() merupakan fungsi yang umum dipakai untuk menampilkan suatu
keluaran pada layar peraga.
10
2. Gunakan pernyataan printf() untuk menampilkan (di layar) nilai dari sebuah variabel
(misalkan namanya = sum) yang bertipe integer.
3. Gunakan pernyataan printf() untuk menampilkan (di layar) string “Welcome” yang
diikuti dengan sebuah perintah ganti baris.
4. Gunakan pernyataan printf() untuk menampilkan (di layar) sebuah karakter dari
variabel yang bertipe karakter (misalkan namanya = letter).
5. Gunakan pernyataan printf() untuk menampilkan (di layar) nilai dari sebuah variabel
float (misalkan namanya = discount).
6. Gunakan pernyataan scanf() untuk membaca masukan sebuah nilai desimal dari
keyboard dan memasukkannya ke sebuah variabel integer (misalkan namanya =
sum).
7. Gunakan pernyataan scanf() untuk membaca masukan nilai float dari keyboard dan
memasukkannya ke sebuah variabel float (misalkan namanya = discount_rate).
11
8. Gunakan pernyataan scanf() untuk membaca masukan sebuah karakter dari keyboard
dan memasukkannya ke sebuah variabel karakter (misalkan namanya = opr).
BAB II
DASAR-DASAR PEMROGRAMAN C
Tujuan :
1. Menjelaskan tentang beberapa tipe data dasar (jenis dan jangkauannya)
2. Menjelaskan tentang Variabel
3. Menjelaskan tentang konstanta
4. Menjelaskan tentang berbagai jenis operator dan pemakaiannya
5. Menjelaskan tentang instruksi I/O
11
12
Untuk tipe data short int, long int, signed int dan unsigned int, maka ukuran memori yang
diperlukan serta kawasan dari masint-masing tipe data adalah sebagai berikut :
Catatan :
Ukuran dan kawasan dari masing-masing tipe data adalah bergantung pada jenis mesin
yang digunakan (misalnya mesin 16 bit bisa jadi memberikan hasil berbeda dengan
mesin 32 bit).
2.2 Variabel
2.2.1 Aturan Pendefinisan Variabel
Aturan penulisan pengenal untuk sebuah variabel, konstanta atau fungsi yang didefinisikan
oleh pemrogram adalah sebagai berikut :
Pengenal harus diawali dengan huruf (A..Z, a..z) atau karakter garis bawah ( _ ).
Selanjutnya dapat berupa huruf, digit (0..9) atau karakter garis bawah atau tanda dollar ($).
Panjang pengenal boleh lebih dari 31 karakter, tetapi hanya 31 karakter pertama yang akan
dianggap berarti.
Pengenal tidak boleh menggunakan nama yang tergolong sebagai kata-kata cadangan (reserved
words) seperti int, if, while dan sebagainya.
tipe daftar-variabel;
nama_variabel = nilai;
Contoh:
int var_bulat = 10;
double var_pecahan =
10.5;
int nilai;
nilai = 10;
Dua pernyataan di atas sebenarnya dapat disingkat melalui pendeklarasian yang disertai
penugasan nilai, sebagai berikut :
Cara seperti ini banyak dipakai dalam program C, di samping menghemat penulisan
pernyataan, juga lebih memberikan kejelasan, khususnya untuk variabel yang perlu diberi
nilai awal (diinisialisasi).
14
2.3 Konstanta
Konstanta menyatakan nilai yang tetap. Berbeda dengan variabel, suatu konstanta tidak
dideklarasikan. Namun seperti halnya variabel, konstanta juga memiliki tipe. Penulisan
konstanta mempunyai aturan tersendiri, sesuai dengan tipe masing-masing.
Konstanta karakter misalnya ditulis dengan diawali dan diakhiri dengan tanda petik
tunggal, contohnya : ‘A’ dan ‘@’.
Konstanta integer ditulis dengan tanda mengandung pemisah ribuan dan tak mengandung
bagian pecahan, contohnya : –1 dan 32767.
Konstanta real (float dan double) bisa mengandung pecahan (dengan tanda berupa titik)
dan nilainya bisa ditulis dalam bentuk eksponensial (menggunakan tanda e), contohnya
: 27.5f (untuk tipe float) atau 27.5 (untuk tipe double) dan 2.1e+5 (maksudnya
2,1 x 105 ).
Konstanta string merupakan deretan karakter yang diawali dan diakhiri dengan tanda
petik-ganda (“), contohnya :“Pemrograman Dasar C”.
2.4 Operator
Operator merupakan simbol atau karakter yang biasa dilibatkan dalam program untuk
melakukan sesuatu operasi atau manipulasi, seperti menjumlahkan dua buah nilai,
memberikan nilai ke suatu variabel, membandingkan kesamaan dua buah nilai. Sebagian
operator C tergolong sebagai operator binary, yaitu operator yang dikenakan terhadap dua
buah nilai (operand). Contoh :
a + b
Simbol + merupakan operator untuk melakukan operasi penjumlahan dari kedua operandnya
(yaitu a dan b). Karena operator penjumlahan melibatkan dua operator ini tergolong sebagai
operator binary.
-c
Simbol - (minus) juga merupakan operator. Simbol ini termasuk sebagai operator unary,
yaitu operator yang hanya memiliki sebuah operand (yaitu c pada contoh ini).
15
# include <stdio.h>
main()
{
float
a,b,c,d; a =
3.0f; b =
4.0f; c =
7.0f;
d = b*b-4*a*c;
printf(“Diskriminan =%f\n”,d);
}
Contoh eksekusi :
Diskriminan = -84.000000
Operator yang telah dituliskan di atas, yang perlu diberi penjelasan lebih lanjut adalah
operator sisa pembagian. Beberapa contoh berikut kiranya akan memperjelas makna dari
operator ini .
• Sisa pembagian bilangan 7 dengan 2 adalah 1 (7 % 2 1)
16
Kegunaan operator ini diantaranya bisa dipakai untuk menentukan suatu bilangan
bulat termasuk ganjil atau genap, berdasarkan logika : “Jika bilangan habis dibagi dua
(sisanya nol), bilangan termasuk genap. Sebaliknya, termasuk ganjil”.
++ operator penaikan
-- operator penurunan
Operator penaikan digunakan untuk menaikkan nilai variabel sebesar satu. Penempatan
operator terhadap variabel dapat dilakukan di muka atau di belakangnya, contohnya :
x = x+1;
y = y+1;
++x;
--y;
atau :
x++;
y--;
bergantung pada kondisi yang dibutuhkan oleh pemrogram. Di bawah ini adalah contoh
yang akan menunjukkan perbedaan pemakaian dan hasil dari ++x dengan x++ (atau
pemakaian y-- dengan –-y).
17
#include <stdio.h>
main()
{
int count = 0, loop;
Contoh eksekusi :
loop = 1, count = 1
loop = 1, count = 2
*)
Bentuk unary + dan unary – memiliki prioritas yang lebih tinggi daripada bentuk binary
+ dan binary -
18
Maka ‘=’ adalah operator penugasan yang akan memberikan nilai dari ungkapan : celcius *
Misalnya :
a = b = 15;
maka nilai variabel ‘a ‘ akan sama dengan nilai variabel ‘b‘ akan sama dengan 15.
x = x + 2;
y = y * 4;
menjadi
x += 2;
y *= 4;
x += 2; kependekan dari x = x + 2;
x -= 2; kependekan dari x = x - 2; x *=
2; kependekan dari x = x * 2;
x /= 2; kependekan dari x = x / 2;
x %= 2; kependekan dari x = x % 2;
x |= 2; kependekan dari x = x | 2; x ^=
2; kependekan dari x = x ^ 2;
String kontrol dapat berupa keterangan yang akan ditampilkan pada layar beserta penentu
format (seperti %d, %f,%c). Penentu format dipakai untuk memberi tahu kompiler mengenai
jenis data yang akan ditampilkan. Argumen sesudah string kontrol (argumen1,
argumen2,...)adalah data yang akan ditampilkan ke layar. Argumen ini dapat berupa
variabel, konstanta dan bahkan ungkapan. Misal :
Untuk menampilkan data bilangan, penentu format yang dipakai berupa salah satu
dari bentuk dalam Tabel 2.5.
untuk menampilkan bilangan real dalam bentuk notasi seperti %f,%E atau %F
%E
%g
%G bergantung pada kepresisian data (digit 0 yang tak berarti tak akan ditampilkan)
Contoh di bawah ini akan menjelaskan perbedaan format %g, %e dan %f dalam
menampilkan bilangan real.
#include <stdio.h>
main()
{
float x = 251000.0f;
21
Tampak bahwa penentu format %e menampilkan bilangan dalam bentuk eksponensial. Jika
penentu fomat yang digunakan berupa %f, bagian pecahan secara default akan ditampilkan
dalam bentuk 6 digit. Sedangkan jika digunakan penentu format %g, maka digit yang tak
berarti tak akan ditampilkan.
Untuk menentukan panjang medan yang disediakan bagi tampilan data, maka sesudah tanda
% dalam penentu format dapat disisipi dengan bilangan bulat yang menyatakan panjang
medan.
Untuk data yang berupa bilangan bulat, misal pada :
printf(“Abad %4d”, 20);
%4d menyatakan medan untuk menampilkan bilangan 20 adalah sepanjang 4 karakter.
printf(“Abad %4d”, 20);
A b a d 2 0
H a r g a : R p 5 0 0 . 0 0
22
Kalau hanya jumlah digit pecahan yang perlu ditentukan, panjang medan tak perlu
disertakan, misal :
hasilnya :
600.00
7500.25
Tampak dalam berbagai jenis data di atas, penentu format yang mengandung panjang
medan, secara default akan menampilkan data dalam bentuk rata kanan terhadap panjang
medan yang diberikan. Untuk data string yang biasanya dikehendaki untuk ditampilkan
dalam bentuk rata kiri, maka sesudah tanda % pada penentu format %s perlu disisipkan
tanda – (minus), contoh :
menyatakan bahwa string akan ditampilkan dalam medan dengan panjang 12 karakter
dan diatur rata kiri. Sehingga tampilan di atas berubah menjadi :
B a h a s a C
#include <stdio.h>
main()
{
int nilai1 = 20;
float nilai2 = 500.0f;
23
Abad 20
500.00
Bahasa C
Bahasa C
________________________________________________________________________
putchar(‘A’);
printf(“%c”,’A’);
radius = 20;
scanf(“%f”,&radius);
24
#include <stdio.h>
main()
{
double radius, keliling, luas;
printf("\nData lingkaran\n");
printf("Jari-jari = %8.2lf\n", radius);
printf("Keliling = %8.2lf\n", keliling);
printf("Luas = %8.2lf\n", luas);
}
Contoh eksekusi :
Data lingkaran
Jari-jari = 5.00
Keliling = 31.40
Luas = 39.25
Penentu format menyatakan jenis data yang akan dibaca. Pada scanf() penentu format dapat
berupa salah satu di antara yang ada pada daftar berikut :
Tabel 2.6 Penentu format scanf()
Pada bentuk scanf(), daftar_argumen dapat berupa satu atau beberapa argumen dan
haruslah berupa alamat. Misalnya hendak membaca bilangan real dan ditempatkan ke
variabel radius, maka yang ditulis dalam scanf() adalah alamat dari radius. Untuk
menyatakan alamat dari variabel, di depan variabel dapat ditambahkan tanda & (tanda &
dinamakan sebagai operator alamat). Sehingga &radius menyatakan alamat dari radius.
Dalam bentuk yang lengkap :
scanf(“%f”, &radius);
berarti (bagi komputer) : “bacalah sebuah bilangan real (%f) dan tempatkan ke alamat dari
radius (&radius)”.
c = getchar();
maka variabel c akan berisi karakter yang diketikkan oleh user atau EOF (end of file) jika
ditemui akhir dari file.
26
Kesimpulan :
• Data merupakan suatu nilai yang bisa dinyatakan dalam bentuk konstanta atau
variabel.
• Konstanta menyatakan nilai yang tetap, sedangkan variabel menyatakan nilai yang
dapat diubah-ubah selama eksekusi berlangsung,
• Variabel yang akan digunakan haruslah dideklarasikan terlebih dahulu, adakalanya
langsung dideklarasikan sekaligus diberi nilai (diinisialisasi).
• Operator merupakan simbol atau karakter yang biasa dilibatkan dalam program untuk
melakukan sesuatu operasi atau manipulasi
• Operator yang terkait dengan operasi aritmatika antara lain adalah operator aritmatika,
operator penurunan dan penaikan, operator penugasan (assignment) dan operator
kombinasi (pemendekan)
• Untuk menampilkan data/informasi ke layar digunakan fungsi printf() dan putchar().
• Untuk memasukkan data melalui keyboard saat eksekusi berlangsung digunakan
fungsi scanf() dan getchar().
Latihan :
#include <stdio.h>
main()
{
int a = 22;
a = a + 5;
a = a-2;
printf("a = %d\n", a);
}
27
(a) x = (2 + 3) – 10 * 2;
(b) x = (2 + 3) – (10 * 2);
(c) x = 10 % 3 * 2 + 1;
#include
<stdio.h> main()
{
char kar = ‘A’;
Tujuan :
1. Menjelaskan tentang operator kondisi (operator relasi dan logika)
2. Menjelaskan penggunaan pernyataan if
3. Menjelaskan penggunaan pernyataan if-else
4. Menjelaskan penggunaan pernyataan if dalam if
5. Menjelaskan penggunaan pernyataan else-if
6. Menjelaskan penggunaan pernyataan switch
28
3.1.1. Operator Relasi
Operator relasi biasa dipakai untuk membandingkan dua buah nilai. Hasil pembandingan
berupa keadaan benar atau salah. Keseluruhan operator relasi pada C ditunjukkan pada Tabel
3-1.
Khususnya untuk operator relasi sama dengan (==) harap dibedakan dengan operator (=)
yang merupakan operator penugasan (assignment). Contoh:
Pembandingan Hasil
1 > 2 Salah
1 < 2 Benar
A == 1 Benar, jika A bernilai 1
Salah, jika A tidak bernilai 1
'A' < 'B' Benar, karena kode ASCII untuk karakter ‘A’
kurang dari kode ASCII untuk karakter ‘B’ *)
kar == Benar, jika kar berisi 'Y'
'Y'
Salah, jika kar tidak berisi 'Y'
*)
Dalam daftar ASCII standar, kode untuk karakter ‘A’ = 65 sedangkan karakter ‘B’ = 66,
‘C’ = 67, ‘D’ = 68 dan seterusnya sampai dengan karakter ‘Z’ = 90.
Operator Makna
&& dan (AND)
|| atau (OR)
! tidak (NOT)
Baik operand1 maupun operand2 dapat berupa ekspresi relasi ataupun ekspresi
logika. Hasil ekspresi bias bernilai benar atau salah. Pada C nilai hasil dari sebuah ekspresi
relasi atau ekspresi logika jika dinyatakan dengan angka adalah :
Salah nilai = 0
Benar nilai != 0 (misalnya nilai = 1)
Tabel 3-3 memberikan penjelasan hasil operasi ekspresi logika yang menggunakan operator
&& maupun || untuk berbagai kemungkinan keadaan operand-nya.
Tampak bahwa operator atau (||) menghasilkan nilai 1 jika ada operand yang
benar. Hasil berupa 0 jika semua operand adalah salah. Adapun operator logika dan (&&)
memberikan hasil 1 hanya jika kedua operand adalah benar.
Beberapa contoh ekspresi logika di antaranya :
(kar > 'A') && (kar < 'Z')
Hasil operasi logika && adalah benar hanya jika kar > 'A' dan kar < 'Z' (dalam
hal ini yang diperbandingkan adalah kode ASCII dari karakter tsb).
(pilihan == 'Y') || (pilihan == 'y')
Hasil operasi logika || adalah benar jika pilihan berupa 'Y' atau 'y'
!operand
31
if (!sudah_benar)
printf(“Masukan Anda salah!\n”);
Pada contoh potongan program di atas, dilakukan pengecekan kondisi terhadap nilai dari
variabel sudah_benar. Jika variabel sudah_benar bernilai 0, maka kondisi
!sudah_benar akan bernilai benar (true) sehingga instruksi :
akan diproses. Penjelasan lebih rinci tentang pengecekan kondisi dengan pernyataan if
dibahas pada sub bab 3.2.
Berdasarkan prioritas yang ditunjukkan pada tabel 3-4, maka ekspresi seperti
Hanya saja penulisan dengan menggunakan tanda kurung akan lebih memberikan kejelasan.
3.2 Pernyataan if
32
if (kondisi ) pernyataan;
salah
kondisi
benar
pernyataan
#include <stdio.h>
main()
{
double total_pembelian, discount = 0; /*
discount diinisialisasi dengan nilai 0 */
33
Contoh eksekusi :
if (kondisi)
{ /* tanda awal pernyataan majemuk*/
pernyataan-1; pernyataan–2; .
.
.
pernyataan-n;
} /* tanda akhir pernyataan majemuk */
Pernyataan-pernyataan yang berada dalam tanda kurung { dan } akan dijalankan hanya bila
kondisi if bernilai benar.
salah
kondisi
benar
pernyataan-1 pernyataan-2
#include <stdio.h>
main()
{
float a, b;
if (b == 0)
printf("\n%g dibagi dengan nol = TAK BERHINGGA\n", a);
else
printf("\n%g dibagi dengan %g = %g\n", a, b, a/b);
}
35
Contoh eksekusi :
Masukkan nilai a : 5
Masukkan nilai b : 0
5 dibagi dengan nol = TAK BERHINGGA
if (kondisi-1)
if (kondisi-2)
.
.
if(kondisi-n)
pernyataan;
else
pernyataan;
.
.
else pernyataan;
else
pernyataan;
Kondisi yang akan diseleksi pertama kali adalah kondisi yang terluar (kondisi-1). Jika
kondisi-1 bernilai salah, maka statemen else yang terluar (pasangan if yang
bersangkutan) yang akan diproses. Jika else (pasangannya tsb) tidak ditulis, maka
penyeleksian kondisi akan dihentikan.
Jika kondisi-1 bernilai benar, maka kondisi berikutnya yang lebih dalam (kondisi-2)
akan diseleksi. Jika kondisi-2 bernilai salah, maka statemen else pasangan dari if yang
bersangkutan yang akan diproses. Jika else (untuk kondisi-2) tidak ditulis, maka
penyeleksian kondisi akan dihentikan.
Dengan cara yang sama, penyeleksian kondisi akan dilakukan sampai dengan kondisin,
jika kondisi-kondisi sebelumnya bernilai benar.
#include <stdio.h>
#include <math.h>
main()
{
float a, b, c, d = 0;
double x1, x2, imaginair;
if (d >= 0) if
(d == 0)
{
x1 = -b / (2 * a);
printf("\nDua akar real kembar yaitu : \n"); printf("x1
= x2 = %g\n", x1);
}
else
{
x1 = (-b + sqrt(d))/(2*a); x2 =
(-b - sqrt(d))/(2*a);
printf("\nDua akar real berlainan yaitu :\n");
printf("x1 = %g\n", x1); printf("x2 = %g\n", x2);
} else
{
imaginair = (sqrt(-d)/(2*a)); x1
= -b/(2*a);
printf("\nDua akar imaginair berlainan yaitu : \n");
printf("x1 = %g + %gi\n", x1, imaginair); printf("x2 =
%g - %gi\n", x1, imaginair);
}
}
Contoh eksekusi :
Jenis operasi yang dikenakan bergantung pada jenis operator ang dimasukkan oleh user.
Oleh karena itu program akan mengecek apakah operator berupa tanda ‘*’, ‘/’, ‘+’, ataukah
tanda ‘-‘ .
Jika operator berupa tanda ‘*’ maka operand1 akan dikalikan dengan operand2.
Jika operator berupa tanda ‘/’ maka operand1 akan dibagi dengan operand2.
Jika operator berupa tanda ‘+’ maka operand1 akan dijumlahkan dengan operand2.
Jika operator berupa tanda ‘-’ maka operand1 akan dikurangi dengan operand2.
Kalau operator yang dimasukkan bukan merupakan salah satu dari jenis operator di atas,
maka ekspresi tersebut tidak akan diproses, dan user akan mendapatkan pesan berupa :
“Invalid operator !”
#include <stdio.h>
main()
{
int valid_operator = 1;
/* valid_operator diinisialisasi dengan logika 1 */ char
operator;
float number1, number2, result;
printf("Masukkan 2 buah bilangan
dan sebuah operator\n");
printf("dengan format : number1
operator number2\n\n"); scanf("%f
38
if(valid_operator)
printf("\n%g %c %g is %g\n", number1, operator,
number2, result ); else
printf("Invalid operator!\n");
}
Contoh eksekusi :
23.2 + 12
23.2 + 12 is 35.2
switch (ekspresi)
39
{
case konstanta-1:
pernyataan-1;
......
break;
case konstanta-2:
.
.
.
case konstanta-n:
pernyataan-n;
.......
break;
default:
.......
.......
break;
}
dengan ekspresi dapat berupa ekspresi bertipe integer atau bertipe karakter. Demikian juga
konstanta-1, konstanta-2, …, konstanta-n dapat berupa konstanta integer atau karakter.
Setiap pernyataan-i (pernyataan-1, … , pernyataan-n) dapat berupa pernyataan tunggal
ataupun pernyataan jamak. Dalam hal ini urutan penulisan pernyataan case tidak
berpengaruh. Proses penyeleksian berlangsung sebagai berikut :
pengujian pada switch akan dimulai dari konstanta-1. Kalau nilai konstanta-1 cocok
dengan ekspresi maka pernyataan-1 dijalankan. Kata kunci break harus disertakan di
bagian akhir setiap pernyataan case, yang akan mengarahkan eksekusi ke akhir switch.
Kalau ternyata pernyataan-1 tidak sama dengan nilai ekspresi, pengujian dilanjutkan
pada konstanta-2, dan berikutnya serupa dengan pengujian pada konstanta-1.
Jika sampai pada pengujian case yang terakhir ternyata tidak ada kecocokan, maka
pernyataan yang mengikuti kata kunci default yang akan dieksekusi. Kata kunci default
ini bersifat opsional.
Tanda kurung kurawal tutup (}) menandakan akhir dari proses penyeleksian kondisi
case.
Di bawah ini contoh program pemakaian pernyataan switch untuk menggantikan if-else
bertingkat pada program kalkulator1.c di atas.
#include <stdio.h>
main()
{
int valid_operator = 1; char
operator;
float number1, number2, result;
switch(operator) {
case '*' : result = number1 * number2; break; case
'/' : result = number1 / number2; break; case '+' :
result = number1 + number2; break; case '-' :
result = number1 - number2; break; default :
valid_operator = 0;
}
if(valid_operator)
printf("%g %c %g is %g\n", number1, operator,
number2,result); else
printf("Invalid operator!\n");
}
Contoh eksekusi :
Masukkan 2 buah bilangan dan sebuah operator
Dengan format : number1 operator number2
23.2 = 12 invalid
operator !
Kesimpulan :
• Operator kondisi adalah operator yang digunakan untuk menghasilkan kondisi benar
(true) dan salah (false), yang terdiri atas operator relasi dan operator logika.
• Operator relasi biasa dipakai untuk membandingkan dua buah nilai.
• Operator logika biasa dipakai untuk menghubungkan ekspresi relasi.
• Untuk penyeleksian kondisi dalam rangka pengambilan keputusan bisa digunakan salah
satu dari pernyataan berikut ini : a. Pernyataan if, bentuk umumnya :
if (kondisi )
pernyataan;
41
if (kondisi) pernyataan-1;
else pernyataan-2;
c. Pernyataan if di dalam if, bentuk umumnya : if
(kondisi-1)
if (kondisi-2)
.
.
if(kondisi-n)
pernyataan; else
pernyataan;
.
.
else
pernyataan;
else
pernyataan;
if (kondisi-1)
pernyataan-1; else
if (kondisi-2)
pernyataan-2;
.
.
else if(kondisi-n)
pernyataan-n; else
pernyataan-(n+1);
.
case konstanta-n:
pernyataan-n;
.......
break;
default:
.......
.......
break;
}
Latihan :
Buatlah potongan program untuk soal-soal di bawah ini
2. Jika variabel total sama dengan variabel tebak, cetaklah nilai dari total, jika tidak
sama, maka cetaklah nilai dari tebak.
3. Jika variabel sum sama dengan 10 dan variabel total kurang dari 20, maka tampilkan
pesan : “Tidak sesuai!”
4. Jika variabel flag sama dengan 1 atau variabel letter bukan ‘X’, maka assign nilai 0
kepada variabel exit_flag, jika tidak, maka set exit_flag sama dengan 1.
Tujuan :
1. Menjelaskan proses pengulangan menggunakan pernyataan for
2. Menjelaskan proses pengulangan menggunakan pernyataan while
3. Menjelaskan proses pengulangan menggunakan pernyataan do-while
4. Menjelaskan penggunaan pernyataan break
5. Menjelaskan penggunaan pernyataan continue
6. Menjelaskan penggunaan pernyataan goto
7. Menjelaskan loop di dalam loop (nested loop) dan contoh kasusnya
8. Menjelaskan penggunaan exit() untuk menghentikan eksekusi program dan contoh
kasusnya
44
45
Contoh penggunaan for, misalnya untuk menampilkan deretan angka sebagai berikut :
20
30
40
50
.
.
.
100
bilangan = 20
salah
bilangan <=100
benar
Cetak bilangan
bilangan =
bilangan + 10
Keluar loop
#include <stdio.h>
main()
{
int bilangan;
Contoh eksekusi :
20
30
40
50
60
70
80
90
100
Pada program di atas, kenaikan terhadap variabel pengendali loop sebesar 10 (positif), yang
dinyatakan dengan ungkapan
bilangan += 10
bilangan = bilangan + 10
Pada contoh yang melibatkan pernyataan for di atas, kenaikan variabel pengendali loop
berupa nilai positif. Sebenarnya kenaikan terhadap variabel pengendali loop bisa diatur
bernilai negatif. Cara ini dapat digunakan untuk memperoleh deret sebagai berikut :
60
50
40
30
20
10
#include <stdio.h>
main()
{
int bilangan;
Contoh eksekusi :
60
50
40
30
20
10
Kadang-kadang dijumpai adanya pernyataan for yang tidak mengandung bagian ungkapan
yang lengkap (beberapa ungkapan dikosongkan). Dengan cara ini, pernyataan
ungkapan
kosong
{
printf(“%d\n”, bilangan);
bilangan += 10;
}
Tampak bahwa ungkapan yang biasa dipakai untuk inisialisasi variabel pengendali loop tak
ada. Sebagai gantinya pengendalian loop diatur sebelum pernyataan for, berupa
bilangan = 20;
Pengosongan ini juga dilakukan pada ungkapan yang biasa dipakai untuk menaikkan nilai
variabel pengendali loop. Sebagai gantinya, di dalam tubuh loop diberikan pernyataan untuk
menaikkan nilai variabel pengendali loop, yaitu berupa
bilangan += 10;
Ungkapan yang tidak dihilangkan berupa bilangan <=100. Ungkapan ini tetap disertakan
karena dipakai sebagai kondisi untuk keluar dari loop.
Sesungguhnya ungkapan yang dipakai sebagai kondisi keluar dari loop juga bisa
dihilangkan, sehingga bentuknya menjadi
49
for (;;)
pernyataan Suatu
pertanyaan mungkin timbul
“Lalu bagaimana caranya
kalau ingin keluar dari loop
pada bentuk di atas?”.
Caranya adalah dengan
menggunakan pernyataan
yang dirancang khusus
untuk keluar dari loop.
Mengenai hal ini akan
dibahas pada sub bab yang
lain.
salah
kondisi
benar
pernyataan
keluar loop
Dengan melihat gambar 4.2, tampak bahwa ada kemungkinan pernyataan yang merupakan
tubuh loop tidak dijalankan sama sekali, yaitu kalau hasil pengujian kondisi while yang
pertama kali ternyata bernilai salah.
Contoh pemakaian while misalnya untuk mengatur agar tombol yang ditekan oleh pemakai
program berupa salah satu diantara 'Y','y', 'T' atau 't'. Impelementasinya :
#include <stdio.h>
main()
{
char pilihan;
/* diberi nilai salah lebih dahulu */
int sudah_benar = 0;
while(!sudah_benar)
{
pilihan = getchar(); /* baca tombol */
sudah_benar = (pilihan == 'Y') || (pilihan == 'y')||
(pilihan == 'T') || (pilihan == 't');
}
Contoh eksekusi :
51
Pilihlah Y atau T
Pilihan anda adalah Y
Inisialisasi terhadap variabel sudah_benar yang akan dijalankan pada kondisi while dengan
memberi nilai awal bernilai false (sudah_benar = 0) dimaksudkan agar tubuh loop
{
pilihan = getchar( ); /* baca tombol */
sudah_benar = (pilihan == 'Y') || (pilihan== 'y')||
(pilihan == 'T') || (pilihan == 't');
}
#include <stdio.h>
52
main()
{
char kar;
int jumkar = 0, jumspasi = 0;
Contoh eksekusi :
Jumlah karakter = 36
Jumlah SPASI = 4
dijalankan lagi. Untuk lebih jelasnya dapat dilihat pada Gambar 4.3. Berdasarkan Gambar
4.3 terlihat bahwa tubuh loop minimal akan dijalankan sekali.
benar
kondisi
salah
keluar loop
i = 0;
do
{
puts("BAHASA C"); i++;
} while(i<10);
Pada program di atas, variabel pencacah dipakai untuk menghitung jumlah tulisan yang
sudah ditampilkan pada layar. Selama nilai pencacah kurang dari 10, maka perintah
54
puts("BAHASA C");
#include <stdio.h>
main()
{
char pilihan;
int sudah_benar;
Contoh eksekusi :
Pilihlah Y atau T
Pilihan anda adalah T
salah (0) tergantung dari nilai pilihan. Kalau pilihan berisi salah satu diantara ‘Y’,‘y’, ‘T’
atau ‘t’, maka sudah berisi salah satu diantara ‘Y’, ‘y’, ‘T’ atau ‘t’, maka sudah_benar akan
berisi benar. Nilai pada vaiabel sudah_benar ini selanjutnya dijadikan sebagai kondisi do-
while. Pengulangan terhadap pembacaan tombol akan dilakukan kembali selama
sudah_benar benilai salah.
for ( ; ; )
{
.
.
if ( …… )
break;
.
.
} /* akhir tubuh loop for */
puts(“\nSelesai…”);
Pada contoh potongan program berikut, pembacaan dan penampilan terhadap tombol yang
ditekan akan berakhir kalau tombol yang ditekan adalah ENTER (‘\n’).
Pernyataan yang digunakan untuk keperluan ini :
Yang menyatakan “Jika tombol yang ditekan berupa ENTER, maka keluarlah dari loop for”.
Untuk lebih jelasnya, perhatikan program di bawah ini.
#include <stdio.h>
main()
{ char kar;
for ( ; ; )
{
kar = getchar(); if(kar
== '\n')
break;
}
printf("Selesai\n");
}
Contoh eksekusi :
Jika pernyataan break berada dalam loop yang bertingkat (nested loop), maka pernyataan
break hanya akan membuat proses keluar dari loop yang bersangkutan (tempat break
dituliskan), bukan keluar dari semua loop.
Program ini digunakan untuk memasukkan data harus diulangi dan hal ini dikendalikan
dengan continue. Untuk mengakhiri pemasukan data, data yang dimasukkan harus bernilai
kurang dari 0. Perlu diketahui kondisi bernilai 1.
while (kondisi) do
{ {
continue; continue;
} } while (kondisi)
#include <stdio.h>
main()
{
int x;
Contoh eksekusi :
7 9 11 13 17 19 21 23 25
Pada program di atas, untuk menghindari agar nilai 15 tidak ditampilkan ke layar, pernyataan
yang digunakan berupa
58
if ( x == 15)
continue;
printf(“%d”,x);
x += 2
x <= 25
1 2 3 4 5 6 7 8
59
1 1 2 3 4 5 6 7 8
2 2 4 6 8 10 12 14 16
3 3 6 9 12 15 18 21 24
4 4 8 12 16 20 24 28 32
5 5 10 15 20 25 30 35 40
6
6 12 18 24 30 36 42 48
7
7 14 21 28 35 42 49 56
8
8 16 24 32 40 48 56 64
#define MAKS 8
main()
{
int baris, kolom, hasil_kali;
Bagian yang terletak dalam bingkai di depan dapat dapat diperoleh melalui
digunakan untuk mencetak suatu deret hasil perkalian dalam satu baris. Untuk berpindah ke
baris berikutnya, pernyataan yang digunakan yaitu
printf(“\n”);
Pernyataan goto
goto cetak;
cetak:
Pernyataan
Mempunyai arti :
• Naikkan nilai pencacah sebesar 1
• Kemudian, jika pencacah kurang dari atau sama dengan 10 maka eksekusi menuju ke
label cetak.
61
Penerapan goto biasanya dilakukan pada loop di dalam loop (nested loop), dengan tujuan
memudahkan untuk keluar dari loop terdalam menuju ke pernyataan yang terletak di luar
loop terluar.
Menurut kebiasaan, nilai nol diberikan pada argumen exit() untuk menunjukkan penghentian
program yang normal. Sedangkan untuk menunjukkan kesalahan, nilai yang diberikan pada
argumen fungsi diisi dengan nilai bukan-nol. Pada contoh program berikut, eksekusi
program akan dihentikan hanya jika tombol ‘X’ ditekan
#include <stdio.h>
#include <stdlib.h>
main() {
char kar;
for ( ; ;)
{
while ((kar = getchar()) == 'X')
exit(0);
}
}
Kesimpulan :
• Pada semua bahasa pemrograman, pengulangan proses ditangani dengan suatu
mekanisme yang disebut loop.
62
while (kondisi)
pernyataan;
• Pernyataan break berfungsi untuk keluar dari loop for, do-while dan while.
• Pernyataan continue digunakan untuk mengarahkan eksekusi ke iterasi (proses)
berikutnya pada loop yang sama.
• Dalam suatu loop bisa terkandung loop yang lain (nested loop).
• Pernyataan goto merupakan intruksi untuk mengarahkan eksekusi ke pernyataan yang
diawali dengan suatu label. Label sendiri berupa suatu pengenal (identifier) yang
diikuti dengan tanda titik dua (:)
• Suatu eksekusi program dapat dihentikan (secara normal) melalui pemanggilan fungsi
exit( ). Hal ini biasa dilakukan, jika di dalam suatu eksekusi terdapat suatu kondisi
yang tak dikehendaki.
Latihan :
Buatlah potongan program untuk soal-soal di bawah ini
1. Gunakan loop for untuk menampilkan nilai 1 sampai dengan 10 dalam baris-baris
yang terpisah.
63
3. Gunakan loop for untuk menjumlahkan seluruh bilangan antara 10 sampai dengan
100 ke dalam sebuah variabel total. Asumsikan bahwa variabel total tidak
diinisialisasi terlebih dahulu dengan nilai nol.
4. Gunakan loop for untuk menampilkan seluruh karaker dari A sampai dengan Z dalam
baris-baris yang terpisah.
5. Hitunglah bilangan triangular dari masukan pengguna, yang dibaca dari keyboard
dengan menggunakan scanf(). Bilangan triangular adalah penjumlahan dari bilangan
masukan dengan seluruh bilangan sebelumnya, sehingga bilangan triangular dari 7
adalah : 7 + 6 + 5 + 4 + 3 + 2 + 1
6. Gunakan loop while untuk menampilkan bilangan integer antara 1 sampai dengan 10
di layar sbb : 123456768910
Tujuan :
1. Memecah program dalam fungsi fungsi yang sederhana.
2. Menjelaskan tentang pemrograman terstruktur.
3. Mengetahui perbedaan antara variabel lokal, eksternal, statis dan register
Fungsi adalah suatu bagian dari program yang dirancang untuk melaksanakan tugas
tertentu dan letaknya dipisahkan dari program yang menggunakannya. Elemen utama dari
program bahasa C berupa fungsi-fungsi, dalam hal ini program dari bahasa C dibentuk dari
kumpulan fungsi pustaka (standar) dan fungsi yang dibuat sendiri oleh pemrogram. Fungsi
banyak digunakan pada program C dengan tujuan :
a. Program menjadi terstruktur, sehingga mudah dipahami dan mudah dikembangkan.
Dengan memisahkan langkah-langkah detail ke satu atau lebih fungsi-fungsi, maka
fungsi utama (main()) menjadi lebih pendek, jelas dan mudah dimengerti.
b. dapat mengurangi pengulangan (duplikasi) kode. Langkah-langkah program yang sama
dan dipakai berulang-ulang di program dapat dituliskan sekali saja secara terpisah dalam
bentuk fungsi-fungsi. Selanjutnya bagian program yang membutuhkan langkah-langkah
ini tidak perlu selalu menuliskannya, tetapi cukup memanggil fungsifungsi tersebut.
Pada umumnya fungsi memerlukan nilai masukan atau parameter yang disebut
sebagai argumen. Nilai masukan ini akan diolah oleh fungsi. Hasil akhir fungsi berupa
sebuah nilai (disebut sebagai return value atau nilai keluaran fungsi). Oleh karena itu
64
65
fungsi sering digambarkan sebagai "kotak gelap" seperti ditunjukkan pada gambar di bawah
ini.
Parameter Keluaran
Fungsi
FUNGSI
Keterangan :
tipe-keluaran-fungsi, dapat berupa salah satu tipe data C, misalnya char atau int . Kalau
penentu tipe tidak disebutkan maka dianggap bertipe int (secara default).
tubuh fungsi berisi deklarasi variabel (kalau ada) dan statemen-statemen yang akan
melakukan tugas yang akan diberikan kepada fungsi yang bersangkutan. Tubuh fungsi
ini ditulis di dalam tanda kurung kurawal buka dan kurung kurawal tutup.
Sebuah fungsi yang sederhana bisa saja tidak mengandung parameter sama sekali
dan tentu saja untuk keadaan ini deklarasi parameter juga tidak ada. Contoh ;
inisialisasi()
{ return(0);
}
Tanda () sesudah nama fungsi menyatakan bahwa fungsi tak memiliki parameter.
Tanda { dan } adalah awal dan akhir fungsi
Nama fungsi
Sepasang tanda kurung, tanpa argumen
inisialisasi() Tak ada tanda titik koma
{ Awal fungsi
return(0); Tubuh fungsi
} Akhir fungsi
return(0);
merupakan pernyataan untuk memberikan nilai keluaran fungsi berupa nol. Selengkapnya
perhatikan program di bawah ini
int inisialisasi();
#include <stdio.h>
main()
{
int x, y;
x = inisialisasi();
printf("x = %d\n", x);
y = inisialisasi();
printf("y = %d\n", y);
67
}
int inisialisasi()
{
return(0);
}
Contoh eksekusi :
x =
0 y
= 0
Program di atas sekaligus menjelaskan bahwa suatu fungsi cukup didefinisikan satu kali
tetapi bisa digunakan beberapa kali. Pada keadaan semacam ini seandainya tubuh fungsi
mengandung banyak pernyataan, maka pemakaian fungsi dapat menghindari duplikasi kode
dan tentu saja menghemat penulisan program maupun kode dalam memori.
x = inisialisasi();
y = inisialisasi();
Bagi suatu fungsi, jika suatu pernyataan return dieksekusi, maka eksekusi terhadap
fungsi akan berakhir dan nilai pada parameter return akan menjadi keluaran fungsi. Untuk
fungsi yang tidak memiliki pernyataan return, tanda } pada bagian akhir fungsi akan
menyatakan akhir eksekusi fungsi.
68
Di bawah ini diberikan contoh sebuah fungsi yang mengandung dua buah pernyataan return.
Fungsi digunakan untuk memperoleh nilai minimum di antara 2 buah nilai yang menjadi
parameternya.
return(y);
}
Pada fungsi di atas terdapat dua buah parameter berupa x dan y. Oleh karena itu fungsi juga
mengandung bagian untuk mendeklarasikan parameter, yang menyatakan x dan y bertipe int.
Adapun penentuan nilai keluaran fungsi dilakukan pada tubuh fungsi, berupa pernyataan
if (x < y)
return(x); else
return(y);
yang menyatakan :
jika x < y maka nilai keluaran fungsi adalah sebesar nilai x.
untuk keadaan lainnya (x >= y) maka keluaran fungsi adalah sebesar y.
Selengkapnya perhatikan program di bawah ini.
#include <stdio.h>
main()
{
int a, b, kecil;
return(y);
}
Contoh eksekusi :
Masukkan nilai a = 4
Masukkan nilai b = 2
return(y);
}
Perhatikan, di depan nama minimum diberikan tipe keluaran fungsi berupa float. Seluruh
parameter sendiri juga didefinisikan dengan tipe float. Selengkapnya adalah sebagai berikut
:
#include <stdio.h>
main()
{
70
float a, b, kecil;
return(y);
}
Contoh eksekusi :
Khusus untuk fungsi yang dirancang tanpa memberikan nilai keluaran (melainkan hanya
menjalankan suatu tugas khusus) biasa didefinisikan dengan diawali kata kunci void (di
depan nama fungsi). Sebagai contoh perhatikan program di bawah ini.
#include <stdio.h>
Contoh eksekusi :
==================================
Progam dibuat oleh Moh. Izzuddin
Tanggal : 12 Juni 2001
Selamat menggunakannya.......
==================================
Bagi kompiler, informasi dalam prototipe akan dipakai untuk memeriksa keabsahan
(validitas) parameter dalam pemanggilan fungsi. Salah satu keuntungannya adalah, kompiler
akan melakukan konversi seandainya antara tipe parameter dalam fungsi dan parameter saat
pemanggilan fungsi tidak sama, atau akan menunjukan kesalahan bila jumlah parameter
dalam definisi dan saat pemanggilan berbeda.
Contoh prototipe fungsi;
atau
Nama fungsi
float jumlah (float, float);
Diakhiri dengan titik koma
Tipe parameter kedua
Tipe parameter pertama
Tipe keluaran fungsi
Gambar 5.4 Prototipe fungsi
#include <stdio.h>
main()
{
float a, b,c;
c = jumlah(a, b);
printf("\nHasil penjumlahan a + b = %g\n", c);
}
float jumlah(float x, float y) /* definisi fungsi */
{
return(x + y);
}
Contoh eksekusi :
Untuk fungsi yang tidak memiliki argumen (contoh program void.c), maka deklarasinya
adalah
void info_program(void);
73
Catatan :
Untuk fungsi-fungsi pustaka, prototipe dari fungsi-fungsi berada di file-file judulnya
(header file). Misalnya fungsi pustaka printf() dan scanf() prototipenya berada pada file
dengan nama stdio.h
Untuk fungsi pustaka pencantuman pada prototipe fungsi dapat dilakukan dengan
menggunakan preprocessor directive #include.
parameter parameter
aktual
formal
Pada pernyataan :
x = jumlah(a, b);
y = jumlah(20.1, 45.6);
a dan b merupakan parameter aktual dari fungsi jumlah() dalam hal ini parameter berupa
variabel. Demikian juga 20.1 dan 45.6 adalah parameter aktual, dalam hal ini berupa
74
konstanta. Bahkan bisa juga parameter aktual berupa ungkapan yang melibatkan operator,
misalnya :
ungkapan
Pemanggilan dengan nilai merupakan cara yang dipakai untuk seluruh fungsi
buatan yang telah dibahas didepan. Pada pemanggilan dengan nilai, nilai dari parameter
aktual akan disalin ke parameter formal. Dengan cara ini nilai parameter aktual tidak bisa
dirubah sekalipun nilai parameter formal berubah. Untuk lebih jelasnya lihat pada fungsi
tukar() pada contoh berikut ini.;
#include <stdio.h>
main()
{
int a,b;
a = 88;
b = 77;
tukar(a,b);
{
int z;
z = x;
x = y;
y = z;
Contoh eksekusi :
Tampak bahwa sekeluarnya dari pemanggilan fungsi tukar(), variabel a dan b (yang
dilewatkan ke fungsi tukar() tidak berubah, walaupun pada fungsi tukar() telah terjadi
penukaran antara parameter x dan y . Mengapa hal ini bisa terjadi ? Sebab x hanyalah
salinan dari a dan y adalah salinan dari b (Lihat gambar 5.6 di bawah ini). Pada saat
pemanggilan fungsi, maka : x bernilai 88 (nilai a)
y bernilai 77 (nilai b)
z = x;
x = y;
y = z;
x y z x y z
88 77 ? 88 77 88
76
mula-mula sesudah : z = x
x y z x y z
77 77 88 77 88 88
sesudah : x = y sesudah : y = z
Gambar 5.6 menjelaskan bahwa a dan b tidak berubah. Yang berubah hanyalah parameter
x dan y.
Pemanggilan dengan referensi (call by reference) merupakan upaya untuk melewatkan
alamat dari suatu variabel ke dalam fungsi. Cara ini dapat dipakai untuk mengubah isi suatu
variabel di luar fungsi dengan pelaksanaan pengubahan dilakukan di dalam fungsi. Sebagai
contoh perhatikan program tukar2.c yang merupakan modifikasi dari tukar1.c. Perubahan
yang pertama terletak dalam definisi fungsi, yang kini berupa
z = *px;
*px = *py;
*py = z;
menyatakan bahwa px dan py adalah suatu variabel pointer. Yang dimaksudkan sebagai
variabel pointer adalah suatu variabel yang menunjuk ke variabel lain. Lebih jelasnya,
variabel pointer berisi alamat dari variabel lain.
77
Adapun pada pemanggilan fungsi, &a dan &b masing-masing berarti "alamat a" dan
"alamat b". Dengan pemanggilan seperti ini, hubungan antara variabel pointer px dan py
dengan variabel a dan b adalah seperti ditunjukkan pada gambar 5.7. Dalam hal ini, px
dikatakan menunjuk variabel a dan py menunjuk variabel b.
px py
alamat a alamat b
a b
Gambar 5.7
Variabel pointer px menunjuk variabel a dan variabel pointer py menunjuk variabel b
#include <stdio.h>
main()
{
int a,b;
a = 88;
b = 77;
z = *px;
*px = *py;
*py = z;
Contoh eksekusi :
Setelah px menunjuk a dan py menunjuk b, proses penukaran isi a dan b dilakukan dengan
cara sebagai berikut :
z = *px; /* 1 */
*px = *py; /* 2 */
*py = z; /* 3 */
Pertama variabel z diisi dengan nilai yang ditunjuk oleh px. Kedua, yang ditunjuk oleh px
diisi dengan yang ditunjuk oleh py (berarti a diisi dengan b). Ketiga, yang ditunjuk oleh py
diberi nilai z. Dengan melalui tiga pernyataan di atas, nilai a dab b dapat diubah di dalam
fungsi.
Catatan : Pembahasan lebih lanjut mengenai pointer dapat dilihat pada bab VIII.
Dalam banyak literatur, variabel lokal disebut juga dengan variabel otomatis.
Variabel yang termasuk dalam golongan ini bisa dideklarasikan dengan menambahkan kata
kuci auto di depan tipe-data variabel. Kata kunci ini bersifat opsional, biasanya disertakan
sebagai penjelas saja. Contoh variabel lokal ditunjukkan pada gambar 5.8.
void fung_x(void)
{
int x;
.
.
. x adalah variabel lokal bagi
} fungsi fung_x()
Gambar 5.8 Variabel lokal
int x;
auto int x;
Penerapan variabel lokal yaitu bila variabel hanya dipakai oleh suatu fungsi (tidak
dimaksudkan untuk dipakai oleh fungsi yang lain). Pada contoh berikut, antara variabel i
dalam fungsi main() dan fung_1() tidak ada kaitannya, sebab masing-masing merupakan
variabel lokal.
80
void fung_1(void);
main()
{
int i = 20;
fung_1();
printf("nilai i di dalam main() = %d\n", i);
}
void fung_1(void)
{
int i = 11;
Contoh eksekusi :
Contoh variabel eksternal ada pda program ekstern1.c yaitu berupa variabel i. Pada
pendeklarasian
int i = 273;
menyatakan bahwa i merupakan variabel eksternal dan diberi nilai awal sama denan 273.
Nilai dari variabel i selanjutnya dapat diubah oleh fungsi tambah() maupun main().
Setiap fungsi tambah() dipanggil maka nilai i akan bertambah satu.
81
#include <stdio.h>
void tambah(void);
main()
{
printf("Nilai awal i = %d\n", i);
i += 7;
printf("Nilai i kini = %d\n", i);
tambah();
printf("Nilai i kini = %d\n", i);
tambah();
printf("Nilai i kini = %d\n", i);
}
void tambah(void)
{
i++;
}
Contoh eksekusi :
Pada contoh di atas, terlihat bahwa i hanya dideklarasikan di bagian atas program, dan tak
dideklarasikan lagi dalam fungsi main() maupun tambah(). Oleh karena i merupakan
variabel eksternal maka dapat digunakan oleh kedua fungsi tsb. Namun ada satu hal yang
perlu diketahui, variabel eksternal haruslah dideklarasikan sebelum definisi fungsi yang
akan mempergunakannya.
Untuk memperjelas bahwa suatu variabel dalam fungsi merupakan variabel eksternal, di
dalam fungsi yang menggunakannya dapat mendeklarasikan variabel itu kembali dengan
82
menambahkan kata kunci extern di depan tipe data variabel. Sebagai contoh, program
ekstern1.c ditulis kembali menjadi seperti pada ekstern2.c.
#include <stdio.h>
void tambah(void);
main()
{
extern int i; /* variabel eksternal */
i++;
}
Contoh eksekusi :
Kalau dalam suatu program terdapat suatu variabel eksternal, suatu fungsi bisa saja
menggunakan nama variabel yang sama dengan variabel eksternal, namun diperlakukan
sebagai variabel lokal. Untuk lebih jelasnya perhatikan contoh program di bawah ini.
#include <stdio.h>
void tambah(void);
main()
{
extern int i; /* variabel eksternal */
i++;
}
Contoh eksekusi :
Pada program di atas, bagi fungsi main() i adalah variabel eksternal. Namun bagi fungsi
tambah(), i merupakan variabel lokal, sebab pada fungsi ini i dideklarasikan tanpa kata
kunci extern. Hal ini terlihat jelas dengan mengamati hasil eksekusi program. Pernyataan:
i++;
Pada fungsi tambah() tidak mempengaruhi nilai i yang ditampilkan pada fungsi main()
(bandingkan dengan hasil eksekusi pada ekstern2.c).
85
Variabel statis diperoleh dengan menambahkan kata kunci static di depan tipe data
variabel. Sebagai contoh perhatikan program di bawah ini.
#include <stdio.h>
void fung_y(void);
main()
{
int y = 20;
fung_y();
fung_y();
printf("Nilai y dalam main() = %d\n", y);
}
void fung_y(void)
{
static int y;
y++;
printf("Nilai y dalam fung_y() = %d\n", y);
}
86
Contoh eksekusi :
#include <stdio.h>
main()
{
register int i; /* variabel register */ int
jumlah = 0;
Contoh eksekusi :
fungsi_a() fungsi_b()
fungsi_c()
#include <stdio.h>
void fungsi_1(void);
void fungsi_2(void);
main()
{
fungsi_1();
}
void fungsi_1()
{
puts("fungsi 1 dijalankan");
fungsi_2();
}
void fungsi_2()
{
puts("fungsi 2 dijalankan");
}
88
Contoh eksekusi :
fungsi 1 dijalankan
fungsi 2 dijalankan
5.9 Rekursi
Fungsi dalam C dapat dipakai secara rekursi, dalam artian suatu fungsi dapat
memanggil dirinya sendiri. Sebagai contoh penerapan fungsi rekursi yaitu untuk
menghitung nilai
xn
dengan n berupa bilagnan bulat positif. Solusi dari persoalan ini dapat berupa :
Jika n = 1, maka xn = x
23 = 2 * 22 22 = 2 * 21 21 = 2
8 4 2
#include <stdio.h>
int faktorial(int);
main() {
int x;
puts("MENCARI FAKTORIAL DARI X!");
printf("Masukkan nilai x (bulat positif) : ");
scanf("%d", &x);
89
Contoh eksekusi :
int faktorial(int m)
{
int i, fak;
fak = 1;
for(i = 1; i <= m; i++) fak =
fak * i;
return(fak);
}
Memerlukan stack dengan ukuran yang lebih besar. Sebab setiap kali fungsi dipanggil,
variabel lokal dan parameter formal akan ditempatkan ke stack dan adakalanya akan
menyebabkan stack tak cukup lagi (stack overflow).
bawah). Pada C suatu program disusun dari sejumlah fungsi dengan tugas tertentu.
Selanjutnya masing masing fungsi dipecah-pecah lagi menjadi fungsi yang lebih kecil.
Pembuatan program dengan cara ini akan memudahkan dalam pencarian kesalahan ataupun
dalam hal pengembangan dan tentu saja mudah dipahami/ dipelajari.
Dalam bentuk diagram, model suatu program C yang terstruktur adalah seperti yang
tertera pada bagan berikut ini. Namun sekali lagi perlu diketahui, bahwa pada C semua
fungsi sebenarnya berkedudukan sederajat.
Fungsi main() terdiri dari fungsi_a() sampai dengan fungsi_n(), menegaskan bahwa
dalam program fungsi main() akan memanggil fungsi_a() sampai dengan fungsi_n().
Adapun fungsi-fungsi yang dipanggil oleh fungsi main() juga bisa memanggil fungsi-fungsi
yang lain.
fungsi utama
main()
fungsi_a() … fungsi_n()
fungsi_a1() … fungsi_am()
Kesimpulan
• Fungsi digunakan untuk memecah program yang besar menjadi program-program
kecil sesuai dengan fungsi masing-masing.
• Fungsi bisa memberikan nilai balik dan bisa tanpa memberikan nilai balik kepada
fungsi yang memanggilnya.
• Fungsi yang memberikan nilai balik harus memiliki tipe dan ditulis didepan nama
fungsi.
91
• Bila fungsi tidak memberikan nilai balik maka fungsi tersebut bertipe “void “ dan
ditulis didepan nama fungsi.
Latihan :
Buatlah potongan program untuk soal-soal di bawah ini
1. Buatlah sebuah fungsi yang berfungsi untuk menampilkan sebuah string (di layar) =
“Pilihan Menu” (misalkan nama fungsinya = menu). Fungsi tersebut tidak
memiliki nilai kembalian (return value) dan juga tidak menerima parameter
masukan apapun.
3. Buatlah sebuah fungsi (misalkan nama fungsinya = cetak) yang berfungsi untuk
menampilkan sebuah string (di layar). Fungsi tersebut tidak memiliki nilai
kembalian (return value), tetapi menerima parameter masukan berupa string yang
akan dicetak (catatan : string merupakan array karakter).
5. Buatlah sebuah fungsi (misalkan nama fungsinya = total) yang berfungsi untuk
menjumlah total nilai dari array integer yang dikirim sebagai parameter masukan
fungsi tsb. Fungsi tersebut memberikan nilai kembalian (return value) bertipe
integer yang berisi total hasil perhitungannya. Dalam hal ini fungsi tsb memiliki 2
parameter masukan berupa array integer dan sebuah variabel integer yang
menunjukkan jumlah elemen dari array tsb.
Tujuan :
1. Menjelaskan tentang array berdimensi satu
2. Menjelaskan tentang array berdimensi dua
3. Menjelaskan tentang array berdimensi banyak
4. Menjelaskan tentang inisialisasi array tak berukuran.
5. Menjelaskan array sebagai parameter fungsi
Dalam beberapa literatur, array sering disebut (diterjemahkan) sebagai larik. Array adalah
kumpulan dari nilai-nilai data bertipe sama dalam urutan tertentu yang menggunakan sebuah
nama yang sama. Nilai-nilai data di suatu array disebut dengan elemen-elemen array. Letak
urutan dari elemen-elemen array ditunjukkan oleh suatu subscript atau indeks.
Array bisa berupa array berdimensi satu, dua, tiga atau lebih. Array berdimensi satu (one-
dimensional array) mewakili bentuk suatu vektor. Array berdimensi dua (twodimensional
array) mewakili bentuk dari suatu matriks atau table
. Array berdimensi tiga (three-dimensional array) mewakili bentuk suatu ruang.
tipe_data nama_var[ukuran];
dengan :
tipe_data : untuk menyatakan tipe dari elemen array, misalnya int, char, float.
nama_var : nama variabel array
ukuran : untuk menyatakan jumlah maksimal elemen array.
91
Contoh pendeklarasian array :
93
float nilai_tes[5];
nilai_tes[1]
total 5 elemen
nilai_tes[2]
nilai_tes[3]
nilai_tes[4]
float nilai_tes[5]
&nilai_tes[2]
berarti “alamat dari nilai_tes[2]”. Perlu diingat bahwa scanf() memerlukan argumen berupa
alamat dari variabel yang digunakan untuk menyimpan nilai masukan.
94
#include <stdio.h>
#define MAKS 5
main()
{
int i;
float total = 0, rata;
float nilai_tes[MAKS]; /* deklarasi array */
Contoh eksekusi :
#include <stdio.h>
main()
{
int bulan, tahun, jhari;
int jum_hari[12] =
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if(bulan == 2)
if(tahun % 4 == 0)
jhari = 29;
else
jhari = 28; else
jhari = jum_hari[bulan-1];
printf("\nJumlah hari dalam bulan %d tahun %d
adalah %d hari\n", bulan, tahun, jhari);
}
Contoh eksekusi :
int jum_hari[12] =
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
merupakan instruksi untuk mendeklarasikan array jum_hari yang memiliki 12 elemen yang
bersifat statis dan sekaligus melakukan inisialisasi terhadap masing-masing elemen array.
#include <stdio.h>
main()
{
int i;
int values[] = {1,2,3,4,5,6,7,8,9};
char word[] = {'H','e','l','l','o'};
printf("\n");
for(i = 0; i < 6; ++i
)
printf("word[%d] is %c\n", i, word[i]);
}
Contoh eksekusi :
values[0] is 1
values[1] is 2
values[2] is 3
values[3] is 4
values[4] is 5
values[5] is 6
values[6] is 7
values[7] is 8
values[8] is 9
word[0] is
H word[1]
is e
word[2] is
l word[3]
is l
word[4] is
o
Perhatikan, pada contoh inisial.c di atas, pendeklarasian nama variabel array tidak disertai
ukuran yang mengindikasikan besarnya array. Dalam kondisi seperti ini, C akan
menginisialisasi ukuran array tersebut sejumlah elemen yang diberikan di dalam kurung
kurawal pada saat proses inisialisasi. Sehingga array values terdiri atas 9 elemen dan array
word memiliki 5 elemen.
97
Nilai 3 untuk menyatakan banyaknya tahun dan 4 menyatakan banyaknya program kursus.
Gambar 6.2 memberikan ilustrasi untuk memudahkan pemahaman tentang array berdimensi
dua.
0 15 83 301
1 8 12 15
2 10 129 257
3
indeks pertama
(program kursus) int data_lulus[4][3];
Sama halnya pada array berdimensi satu, data array aka ditempatkan pada memori yang
berurutan. Perhatikan Gambar 6.3.
0 1 2
0 540
1
2
3
data_lulus[0][1] = 540;
#include <stdio.h>
main(
) {
int tahun, kode_program;
int data_lulus[4][3] ;
data_lulus[1][0] = 15;
data_lulus[1][1] = 83;
data_lulus[1][2] = 301;
100
data_lulus[2][0] = 8;
data_lulus[2][1] = 12;
data_lulus[2][2] = 15;
data_lulus[3][0] = 10;
data_lulus[3][1] = 129;
data_lulus[3][2] = 257;
Contoh eksekusi :
0 1 1 1 1 1 0 0
0 1 0 0 0 1 0 0
0 1 0 0 0 1 0 0
1 1 1 1 1 1 1 0
1 1 0 0 0 0 1 0
1 1 0 0 0 0 1 0
1 1 0 0 0 0 1 0
0 0 0 0 0 0 0 0
int huruf_A[8][8] = {
{ 0, 1, 1, 1, 1, 1, 0, 0 } ,
{ 0, 1, 0, 0, 0, 1, 0, 0 } ,
{ 0, 1, 0, 0, 0, 1, 0, 0 } ,
{ 1, 1, 1, 1, 1, 1, 1, 0 } ,
{ 1, 1, 0, 0, 0, 0, 1, 0 } ,
{ 1, 1, 0, 0, 0, 0, 1, 0 } ,
{ 1, 1, 0, 0, 0, 0, 1, 0 } ,
{ 0, 0, 0, 0, 0, 0, 0, 0 }
};
int huruf_A[8][8] =
{ 0, 1, 1, 1, 1, 1, 0, 0,
0, 1, 0, 0, 0, 1, 0, 0,
0, 1, 0, 0, 0, 1, 0, 0,
1, 1, 1, 1, 1, 1, 1, 0,
1, 1, 0, 0, 0, 0, 1, 0,
1, 1, 0, 0, 0, 0, 1, 0,
1, 1, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
Contoh program berikut memenfaatkan data yang ada pada array huruf_A untuk
membentuk karakter A dengan ukuran besar. Setiap nilai satu pada array akan diganti dengan
karakter ber-ASCII 219 (DBh) dan nilai 0 akan diganti dengan karakter spasi.
#include <stdio.h>
main()
{
int i,j;
int huruf_A[8][8] = {
{ 0, 1, 1, 1, 1, 1, 0, 0 } ,
{ 0, 1, 0, 0, 0, 1, 0, 0 } ,
{ 0, 1, 0, 0, 0, 1, 0, 0 } ,
{ 1, 1, 1, 1, 1, 1, 1, 0 } ,
{ 1, 1, 0, 0, 0, 0, 1, 0 } ,
102
{ 1, 1, 0, 0, 0, 0, 1, 0 } ,
{ 1, 1, 0, 0, 0, 0, 1, 0 } ,
{ 0, 0, 0, 0, 0, 0, 0, 0 }
};
Contoh eksekusi :
sebagai contoh :
int data_huruf[2][8][8];
Sama halnya dengan array berdimensi satu atau dua, array berdimensi banyak juga bisa
diinisialisasi. Contoh inisialisasi array berdimensi tiga :
# include <stdio.h>
main()
{
int i, j, k;
int data_huruf[2][8][8] = {
{{ 0, 1, 1, 1, 1, 1, 0, 0 },
{ 0, 1, 0, 0, 0, 1, 0, 0 },
{ 0, 1, 0, 0, 0, 1, 0, 0 },
{ 1, 1, 1, 1, 1, 1, 1, 0 },
{ 1, 1, 0, 0, 0, 0, 1, 0 },
{ 1, 1, 0, 0, 0, 0, 1, 0 },
{ 1, 1, 0, 0, 0, 0, 1, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 }
},
{{1, 1, 1, 1, 1, 1, 0, 0 },
{1, 0, 0, 0, 0, 1, 0, 0 },
{1, 0, 0, 0, 0, 1, 0, 0 },
{1, 1, 1, 1, 1, 1, 1, 0 },
{1, 1, 0, 0, 0, 0, 1, 0 },
{1, 1, 0, 0, 0, 0, 1, 0 },
{1, 1, 1, 1, 1, 1, 1, 0 },
{0, 0, 0, 0, 0, 0, 0, 0 }
}
};
Contoh Eksekusi :
int skala[] =
{ 1, 2, 4, 6, 8 };
merupakan pendeklarasian array berdimensi satu yang tak berukuran. Secara otomatis
skala[ 0 ] bernilai 1 skala[ 1 ] bernilai 2 skala[ 2 ] bernilai 4 skala[ 3 ] bernilai
6 skala[ 4 ] bernilai 8
106
Contoh lain :
char konversi[][2] =
{ ’A’, ’T’,
’E’, ’M’,
’I’, ’V’,
’O’, ’S’,
’U’, ’J’,
};
Contoh berikut akan menyandikan suatu kalimat yang dimasukkan melalui keyboard dengan
menggunakan data yang ada pada tabel konversi. Misal, huruf A akan diganti menjadi T,
huruf T akan diganti menjadi A.
#include <stdio.h>
#include <stdlib.h>
#define JUM_KOLOM 2
#define MAX_KAR 256
main()
{
char konversi[][JUM_KOLOM] = {
'A', 'T',
'a', 't',
'E', 'M',
'e', 'm',
'I', 'V',
'i', 'v',
'O', 'S',
'o', 's',
107
'U', 'J',
'u', 'j'
};
Contoh Eksekusi :
sizeof(konversi)/JUM_KOLOM)
merupakan ungkapan untuk memperoleh banyaknya baris (ukuran dari dimensi pertama)
dalam array konversi. Dengan cara ini tabel konversi dapat diperluas tanpa perlu
memberitahu banyaknya jumlah dimensi pertama secara ekplisit.
109
50.5 30.3
0
1 30.3 50.5
2
3
20.2 20.2
4
25.2 25.2
i= 1 j
=2 j 31.3 31.3 31.3 31.3 = 3
j=4
0 20.2 20.2
1 50.5 30.3
2
3
4 30.3 50.5
25.2 25.2
0 20.2 20.2
1 2
25.2 25.2 3 4
50.5 30.3
30.3 50.5
i =3 j=4 Hasil akhir
31.3 31.3
111
20.2
25.2
30.3
50.5
30.3
31.3
31.3
50.5
0
1
2
3
4
Gambar 6.6 Proses pengurutan data secara ascending dengan metode Buble Sort
#define MAKS 20
main(
) {
float data[MAKS];
int jum_data;
pemasukan_data(data, &jum_data);
pengurutan_data(data, jum_data);
penampilan_data(data, jum_data);
}
void pemasukan_data(float x[], int *pjumlah)
{
int jum, i;
*pjumlah = jum;
}
void pengurutan_data(float x[], int jumlah)
{
int i, j;
float smtr;
Contoh Eksekusi :
Jumlah data = 5
Data ke-1 : 50.5
Data ke-2 : 30.3
Data ke-3 : 20.2
Data ke-4 : 25.2
Data ke-5 : 31.3
Data setelah diurutkan
Pada fungsi untuk pemasukan data, pengurutan data maupun penampilan data,
data[i]
&nama_array[indeks]
Misalnya,
&data[1]
&data[0]
data
Suatu array berdimensi satu dalam parameter formal dideklarasikan dengan bentuk
tipe nama_array[]
dengan di dalam tanda kurung siku tak disebutkan mengenai jumlah elemen. Jumlah elemen
dinyatakan dalam parameter tersendiri (atau dinyatakan dalam bentuk variabel eksternal).
Untuk array berdimensi lebih dari satu, kurung siku terkirilah yang kosong.
Kesimpulan :
• Array adalah kumpulan dari nilai-nilai data bertipe sama dalam urutan tertentu yang
menggunakan sebuah nama yang sama.
• Nilai-nilai data di suatu array disebut dengan elemen-elemen array.
• Letak urutan dari elemen-elemen array ditunjukkan oleh suatu subscript atau indeks.
• Array bisa berupa array berdimensi satu, dua, tiga atau lebih.
• Data array akan disimpan dalam memori yang berurutan, dengan elemen pertama
mempunyai indeks yang bernilai 0.
• Sebuah array dapat diinisialisasi sekaligus pada saat dideklarasikan, caranya saat
mendeklarasikan array, nilai-nilai yang diinisialisasikan dituliskan di antara kurung
kurawal ({}) yang dipisahkan dengan koma.
Latihan :
Buatlah potongan program untuk soal-soal di bawah ini
2. Masukkan karakter ‘Z’ pada elemen yang ke-empat dari array letters.
3. Gunakan loop for untuk menghitung nilai akumulasi (total) dari seluruh isi sebuah
array integer (array of int, misalkan namanya = numbers) yang memliki 5 elemen.
115
4. Deklarasikan sebuah array multidimensi yang elemennya bertipe float (array of float,
misalkan namanya = balances) yang memiliki 3 baris dan 5 kolom.
5. Gunakan loop for untuk menghitung nilai total dari seluruh isi array balances di atas.
6. Deklarasikan sebuah array karakter (array of char, mislakan namanya = words) dan
sekaligus inisialisasikan dengan nilai string = “Hello”
7. Deklarasikan sebuah array karakter (array of char, mislakan namanya = stuff) dengan
alokasi 50 elemen. Selanjutnya isikan dengan nilai string = “Welcome” pada body
programnya (bukan pada saat deklarasi)
8. Gunakan statemen printf() untuk menampilkan (di layar) isi elemen ke-tiga dari
sebuah array integer (array of int, misalkan namanya = totals)
9. Gunakan statemen printf() untuk menampilkan (di layar) string yang merupakan isi
dari sebuah array karakter (array of char, misalkan namanya = words)
10. Gunakan statemen scanf() untuk membaca string masukan dari keyboard dan
memasukkannya ke array words.
11. Tuliskan loop for untuk membaca 5 karakter (gunakan statemen scanf()) dan
memasukkannya ke dalam array words, mulai dari indeks 0.
BAB VII
STRING
Tujuan :
1. Menjelaskan tentang konsep string
2. Menjelaskan operasi I/O pada string.
3. Menjelaskan cara mengakses elemen string
4. Menjelaskan berbagai fungsi mengenai string
“ABCDE”
Nilai string ini disimpan dalam memori secara berurutan dengan komposisi sebagai berikut:
A B C D E \0
113
114
Setiap karakter akan menempati memori sebesar 1 byte. Byte terakhir otomatis akan berisi
karakter NULL (\0). Dengan mengetahui bahwa suatu string diakhiri nilai NULL, maka
akhir dari nilai suatu string akan dapat dideteksi. Sebagai sebuah array karakter, karakter
pertama dari nilai string mempunyai indeks ke-0, karakter kedua mempunyai indeks ke-1,
dan seterusnya.
char name[15];
yang menyatakan bahwa name adalah variabel string dengan nilai awal berupa string :
“RINI” . Bentuk inisialisasi yang lebih singkat :
Pada bentuk ini, karakter NULL tidak perlu ditulis. Secara implisit akan disisipkan oleh
kompiler. Perlu diperhatikan, bila name dideklarasikan sebagai string, penugasan
(assignment) suatu string ke variabel string seperti
name = “RINI”;
adalah tidak diperkenankan. Pengisian string ke variabel string akan dibahas pada sub bab
berikutnya.
115
#include <stdio.h>
gets(nama_array);
atau
#include <stdio.h>
scanf(“%s”, nama_array);
Perhatikan : nama_array adalah variabel bertipe array of char yang akan digunakan
untuk menyimpan string masukan.
Æ Di depan nama_array tidak perlu ada operator & (operator alamat), karena nama_array
tanpa kurung siku sudah menyatakan alamat yang ditempati oleh elemen pertama dari
array tsb.
Æ Kalau memakai scanf(), data string masukan tidak boleh mengandung spasi.
Di bawah ini diberikan contoh program untuk memasukkan data nama seseorang ke dalam
array bernama name.
#include <stdio.h>
main()
{
char name[15];
Contoh eksekusi :
name :
name : S A I F U D D I N \0
karakter NULL
byte sisa tak dipakai
Pada gambar di atas nama array tanpa kurung siku (name) menyatakan alamat dari lokasi
data string. Dan dengan pemasukan data seperti di atas, lokasi memori yang terletak sesudah
lokasi yang berisi ‘N’ akan secara otomatis terisi karakter NULL (lihat gambar 7.2)
Perlu diketahui, fungsi gets() akan membaca seluruh karakter yang diketik melalui keyboard
sampai tombol ENTER ditekan. Dalam hal ini tidak ada pengecekan terhadap batasan
panjang array yang merupakan argumennya. Jika string yang dimasukkan melebihi ukuran
array, maka sisa string (panjang string masukan dikurangi ukuran array plus karakter NULL)
akan ditempatkan di lokasi sesudah bagian akhir dari array tersebut. Tentu saja kejadian
seperti ini bisa menimbulkan hal yang tidak diinginkan, misalnya berubahnya isi variabel
yang dideklarasikan sesudah array tersebut karena tertumpuki oleh string yang dimasukkan
(overwrite), atau perilaku program yang sama sekali berbeda dengan kemauan user yang
dalam hal ini pelacakan kesalahannya (debugging) sangat sulit dilakukan, atau bahkan
terjadi penghentian program secara tidak normal.
Untuk mengatasi hal itu, disarankan untuk menggunakan fungsi fgets() untuk
menggantikan fungsi gets() dalam memasukkan data string.
Bentuk umum pemakaian fgets() adalah :
#include <stdio.h>
fgets(nama_array, sizeof nama_array, stdin);
Untuk lebih jelasnya, perhatikan contoh penggunaan fungsi fgets() ini pada contoh program
untuk menghitung karakter masukan (hitkar.c) di halaman 118.
#include <stdio.h>
puts(var_string);
atau
printf("%s",var_string);
Dalam hal ini var_string adalah sebuah variabel yang berupa sebuah array of char. Fungsi
puts() akan menampilkan isi dari var_string dan secara otomatis menambahkan karakter
'\n' di akhir string. Sedangkan fungsi printf() akan menampilkan isi variabel string tanpa
memberikan tambahan '\n'. Sehingga, agar kedua pernyataan di atas memberikan keluaran
yang sama, maka pada pernyataan printf() dirubah menjadi :
printf("%s\n", var_string);
Contoh program berikut akan menampilkan isi variabel kompiler_c, berdasarkan dua
bentuk inisialisasi string yang dibahas pada sub bab 7.3
#include <stdio.h>
void bentuk1(void);
void bentuk2(void);
main()
{
bentuk1();
bentuk2();
}
void bentuk1(void)
{
char kompiler_c[] =
{'V','i','s','u','a','l',' ','C','+','+','\0'};
puts(kompiler_c);
}
void bentuk2(void)
{
char kompiler_c[] = "Visual C++";
printf("%s\n", kompiler_c);
}
118
Contoh eksekusi :
Visual C++
Visual C++
#include <stdio.h>
main()
{
int i, jumkar = 0;
char teks[MAKS];
Contoh eksekusi :
Jumlah karakter = 26
Perhitungan jumlah karakter dari string teks dapat dilakukan dengan memeriksa elemen dari
string dimulai dari posisi yang pertama (indeks ke-0) sampai ditemukannya karakter NULL.
Elemen yang ke-i dari teks dinyatakan dengan
teks[i]
Pemeriksaan terhadap teks[i] selama tidak berupa karakter NULL (dimulai dari indeks ke0)
dilakukan dengan instruksi
Kondisi teks[i] pada for mempunyai makna yang secara implisit berupa
teks[i] != ‘\0’;
atau “karakter yang ke-i dari teks tidak sama dengan karakter NULL”
Contoh berikut ini akan memberikan gambaran mengenai cara menyalin nilai ke suatu
variabel string.
120
#include <stdio.h>
#define MAKS 30
main()
{ int i;
char asal[] = “Saya menyukai bahasa C”;
char hasil[MAKS];
i=0;
while (asal[i] != ‘\0’)
{
hasil[i] = asal[i]; i++;
} hasil[i] = ‘\0’; /* beri karakter
NULL */
printf(“Isi hasil : %s\n”, hasil);
}
Contoh eksekusi :
Untuk menyalin isi variabel string keterangan ke kalimat, pernyataan yang digunakan
berupa
i=0;
while (keterangan[i] != ‘\0’)
{
kalimat[i] = keterangan[i]; i++;
}
kalimat[i] = ‘\0’;
Bentuk yang lebih singkat untuk melakukan penyalinan dari keterangan ke kalimat berupa
i=0;
121
Dengan penulisan seperti di atas, penyalinan karakter NULL juga akan dilakukan secara
otomatis. Setelah menyalin karakter NULL (karena kondisi bernilai NULL) maka eksekusi
terhadap loop akan dihentikan. Dengan demikian sekeluarnya dari loop tidak perlu lagi ada
pernyataan.
kalimat[i] = ‘\0’;
#include <string.h>
strcpy(tujuan, asal)
Fungsi ini dipakai untuk menyalin string asal ke variabel string tujuan termasuk
karakter '\0'. Keluaran dari fungsi ini (return value) adalah string tujuan. Dalam hal ini,
variabel tujuan haruslah mempunyai ukuran yang dapat digunakan untuk menampung
seluruh karakter dari string asal. Contoh implementasinya bisa dilihat pada program
salinstr2.c di bawah ini.
#include <stdio.h>
#include <string.h>
#define MAKS 80
main()
{
122
char str1[MAKS];
char str2[]="ABCDE";
Contoh eksekusi :
#include <string.h>
strlen(var_string);
Fungsi ini digunakan untuk memperoleh banyaknya karakter di dalam string yang
menjadi argumennya (var_string). Keluaran dari fungsi ini adalah panjang dari var_string.
Karakter NULL tidak ikut dihitung. Contoh implementasinya bisa dilihat pada program
panjangstr.c di bawah ini.
#include <stdio.h>
#include <string.h>
main()
{
char salam[] = "Halo";
Contoh eksekusi :
Panjang string = 4 karakter
123
#include <string.h>
strcat(tujuan, sumber);
Menggabungkan dua buah nilai string tidak dapat dilakukan dengan operator ‘+’,
karena operator ini bukan operator untuk operasi string. Penggabungan dua buah nilai string
dapat dilakukan dengan fungsi pustaka strcat() dengan menambahkan string sumber ke
bagian akhir dari string tujuan. Keluaran dari fungsi ini adalah string tujuan. Contoh
implementasinya bisa dilihat pada program gabungstr.c di bawah ini.
#define PJG 15
main()
{ char str1[PJG], str2[PJG];
Contoh eksekusi :
Dalam hal ini str1 (“sala”) digabungkan dengan str2 (“tiga”) dengan hasilnya berada di str1
(“salatiga”).
124
#include <string.h>
strcmp(str1, str2);
Fungsi ini dipakai untuk membandingkan string str1 dengan string str2. Keluaran
dari fungsi ini bertipe int yang berupa nilai :
-1, jika str1 kurang dari str2 0, jika str1 sama
dengan str2
1, jika str1 lebih dari str2
Pembandingan dilakukan untuk karakter pada posisi yang sama dari str1 dan str2, dimulai
dari karakter terkiri. Acuan pembandingan dari dua buah karakter didasarkan oleh nilai
ASCII-nya. Misal, karakter ‘A’ lebih kecil daripada ‘B’ dan karakter ‘B lebih kecil daripada
‘C’. Contoh implementasinya bisa dilihat pada program bandingstr.c di bawah ini.
#include <stdio.h>
#include <string.h>
main()
{ char str1[]="HALO”;
char
str2[]="Halo";
char
str3[]="HALO”;
Contoh eksekusi :
#include <string.h>
strchr(var_string, kar);
Fungsi ini dapat digunakan untuk mencari suatu nilai karakter yang berada dalam
suatu nilai string. Dalam hal ini adalah mencari karakter kar dalam string var_string.
Keluaran dari fungsi ini adalah alamat posisi dari karakter pertama pada nilai string, yang
sama dengan karakter yang dicari. Jika karakter yang dicari tidak ada dalam nilai string,
maka fungsi ini akan memberikan hasil nilai pointer kosong (null). Contoh implementasinya
bisa dilihat pada program carikar.c di bawah ini.
#include <stdio.h>
#include <string.h>
main()
{ char str[]="ABcde”; /* inisialisasi string */
char *hasil1,*hasil2;
/* var bertipe pointer to char, agar bisa ditampilkan isi
dari alamat yang ditunjuk oleh hasil1 & hasil2 */
Contoh eksekusi :
126
Contoh di atas menunjukkan penggunaan fungsi strchr() untuk mencari nilai karakter ‘B’
dan karakter ‘X’ dalam string ‘ABcde’. Karakter ‘B’ ada dalam nilai string yang dicari,
sehingga fungsi strchr() memberikan hasil alamat dari karakter B tersebut yang kemudian
alamat ini disimpan dalam variabel pointer hasil1. Jika variabel pointer hasil1 ini
ditampilkan dengan menggunakan kode format untuk nilai string (%s), maka mulai dari
alamat tersebut sampai dengan akhir dari nilai string yang bersangkutan akan ditampilkan,
sehingga didapatkan keluaran :
Sedangkan pencarian karakter ‘X’ memberikan hasil null karena karakter tersebut tidak
ditemukan dalam string ‘ABcde”, sehingga didapatkan keluaran :
Keterangan lebih lanjut tentang pointer ini, akan dibahas pada bab VIII.
Kesimpulan :
• String merupakan bentuk data yang biasa dipakai dalam bahasa pemrograman untuk
keperluan menampung dan memanipulasi data teks.
• Pada bahasa C, string bukanlah merupakan tipe data tersendiri, melainkan hanyalah
kumpulan dari nilai-nilai karakter yang berurutan dalam bentuk array berdimensi satu
• Suatu konstanta string ditulis dengan diawali dan diakhiri tanda petik ganda
• Pemasukan data string ke dalam suatu variabel biasa dilakukan dengan fungsi gets() atau
scanf().
• Untuk menampilkan isi variabel string, fungsi yang digunakan adalah puts() atau printf().
• Untuk mengoperasikan suatu nilai string ada beberapa fungsi pustaka yang
prototypeprototype-nya berada di file judul string.h, sehingga dalam suatu program
yang di dalamnya terdapat manipulasi string, haruslan ditambah : #include <string.h>.
• Beberapa fungsi untuk manipulasi string adalah sbb :
a. Fungsi strcpy() untuk menyalin nilai string
127
Latihan :
Buatlah potongan program untuk soal-soal di bawah ini
1. Ketikkan sebuah kalimat melalui keyboard dengan menggunakan gets() (atau fgets())
kemudian didapatkan keluaran berupa laporan tentang jumlah huruf kecil dan huruf
kapital dalam kalimat tsb.
2. Masukkan nama Anda, rubah ke dalam huruf besar semua, balikkan urutan hurufnya,
selanjutnya tampilkan hasilnya di layar.
4. Ketikkan sebuah kalimat, kemudian tampilkan kalimat tsb satu kata perbaris.
Asumsikan ada satu spasi yang memisahkan setiap kata dan kalimat diakhiri dengan
sebuah tanda titik.
Catatan : disebut palindrom adalah bila urutan kalimat dibalik akan menghasilkan
kalimat yang sama. Gunakan berbagai fungsi berkaitan dengan string yang
sudah dijelaskan di atas.
BAB VIII
POINTER
Tujuan :
1. Menjelaskan tentang konsep dari variabel pointer
2. Menjelaskan tentang pointer array
3. Menjelaskan tentang pointer string
4. Menjelaskan tentang array pointer
5. Menjelaskan tentang pointer dalam fungsi
6. Menjelaskan tentang pointer sebagai parameter fungsi
7. Menjelaskan tentang pointer yang menunjuk pointer.
px
zzzz 1000
Address
?
1000
x
dengan tipe dapat berupa sembarang tipe yang sudah dibahas pada bab-bab sebelumnya,
maupun bab-bab berikutnya. Adapun nama_variabel adalah nama dari variabel pointer.
Sebagai contoh :
Contoh pertama menyatakan bahwa px adalah variabel pointer yang menunjuk ke suatu data
bertipe int, sedangkan contoh kedua masing pch1 dan pch2 adalah variabel pointer yang
menunjuk ke data bertipe char.
menyatakan variabel
pointer
&x
berarti “alamat dari variabel x”. Adapun contoh pemberian alamat x ke suatu variabel pointer
px (yang dideklarasikan sebagai pointer yang menunjuk ke data bertipe int) yaitu :
px = &x;
130
Pernyataan di atas berarti bahwa px diberi nilai berupa alamat dari variabel x. Setelah
pernyataan tersebut dieksekusi barulah dapat dikatakan bahwa px menunjuk ke variabel x.
*px
yang menyatakan “isi atau nilai variabel/data yang ditunjuk oleh pointer px” . Sebagai
contoh jika y bertipe int, maka sesudah dua pernyataan berikut
px = &x;
y = *px;
y akan berisi nilai yang sama dengan nilai x. Untuk lebih jelasnya perhatikan contoh
program ptr1.c
/* Program : ptr1.c */
#include <stdio.h>
main()
{
int y, x = 87; /* x & y bertipe int */
int *px;
/* var pointer yang menunjuk ke data yang bertipe int */
Contoh eksekusi :
Alamat x = 0012FF78
Isi px = 0012FF78
Isi x = 87
Nilai yang ditunjuk oleh px = 87
Nilai y = 87
px = &x;
y = *px;
y = x;
px = &x;
y = *px;
maka y tidaklah berisi nilai x, sebab px belum diatur agar menunjuk ke variabel x. Hal
seperti ini harap diperhatikan. Kalau program melibatkan pointer, dan pointer belum
diinisialisasi, ada kemungkinan akan terjadi masalah yang dinamakan “bug” yang bisa
mengakibatkan komputer tidak dapat dikendalikan (hang).
Selain itu tipe variabel pointer dan tipe data yang ditunjuk harus sejenis. Bila tidak sejenis
maka akan terjadi hasil yang tidak diinginkan. Lebih jelasnya perhatikan contoh program
ptr2.c.
132
/* Program : ptr2.c */
#include <stdio.h>
main()
{
int *pu; int
nu; int u =
1234;
pu = &u;
nu = *pu;
maka pu akan menunjuk data berukuran 4 byte (tipe float) sekalipun u berukuran 2 byte (tipe
int). Oleh karena itu, pernyataan
nu =
*pu;
tidak akan membuat nu berisi nilai u. untuk lebih jelasnya lihat gambar berikut.
double *pu;
float nu; data yang int u; u ditunjuk oleh pu
--------
pu = &u;bukan bagian dari
u
Gambar 8.3 Ilustrasi kesalahan yang terjadi karena tipe tidak sejenis
133
merupakan instruksi untuk mengubah nilai variabel d secara tak langsung. Perintah di atas
berarti “jumlahkan yang ditunjuk pd dengan 10 kemudian berikan ke yang ditunjuk oleh pd”,
atau identik dengan pernyataan
d =
d + 10;
pd =
&d;
maka pernyataan
/* Program : ptr3.c */
#include <stdio.h>
main()
{
float d = 54.5f, *pd;
pd = &d; *pd
+= 10;
Contoh eksekusi :
dan
int
*ptgl;
maka ptgl akan berisi alamat dari elemen array tgl_lahir yang berindeks nol. Instruksi di
atas bisa juga ditulis menjadi
ptgl = tgl_lahir;
sebab nama array tanpa tanda kurung menyatakan alamat awal dari array. Sesudah
penugasan seperti di atas,
*ptgl
dengan sendirinya menyatakan elemen pertama (berindeks sama dengan nol) dari array
tgl_lahir. Hal ini bisa dilihat melalui pembuktian program berikut.
/* Program : ptr4.c */
#include <stdio.h>
main()
{
static int tgl_lahir[] = {16, 4, 1974};
int *ptgl;
ptgl = tgl_lahir;
Contoh eksekusi :
136
/* Program : ptr5.c */
#include <stdio.h>
main()
{
static int tgl_lahir[] = {16, 4, 1974};
int *ptgl, i;
ptgl = tgl_lahir;
Contoh eksekusi:
/* Program : ptr6.c */
#include <stdio.h>
main()
{
static int tgl_lahir[] = {16, 4, 1974};
int i;
int *ptgl;
ptgl = tgl_lahir;
/* Program : ptr4.c */
#include <stdio.h>
main()
{
/* pkota menunjuk konstanta string “SEMARANG” */
char *pkota = “SEMARANG”;
Contoh eksekusi :
S E M A R A N G \0
tetapi sebenarnya kedua pernyataan inisialisasi di depan tidaklah tepat sama. Sebab pkota
adalah pointer (menyatakan alamat) yang dengan mudah dapat diatur agar menunjuk ke
string lain (bukan string “SEMARANG”), sedangkan kota adalah array (array menyatakan
alamat yang konstan, tak dapat diubah). Perhatikan dua program di bawah ini
/* Program : arrnama.c
Menukarkan isi 2 string tanpa pemakaian pointer */
#include <stdio.h>
#include <string.h>
#define PANJANG 20
main()
{
char namax[PANJANG];
puts("SEMULA : ");
printf("nama1 --> %s\n",
nama1); printf("nama2 -->
%s\n", nama2);
strcpy(namax, nama1);
strcpy(nama1, nama2);
strcpy(nama2, namax);
puts("KINI : ");
printf("nama1 --> %s\n", nama1);
printf("nama2 --> %s\n", nama2);
}
/* Program : ptrnama.c
Menukarkan isi 2 string dengan fasilitas pointer */
#include <stdio.h>
#include <string.h>
139
main()
{
char *namax;
puts("SEMULA : ");
printf("nama1 --> %s\n", nama1);
/* nama1:pointer yg menunjuk ke string JAMES BOND */
printf("nama2 --> %s\n", nama2);
/* nama2:pointer yg menunjuk ke string HERCULE POIROT */
namax = nama1;
nama1 = nama2; nama2
= namax;
puts("KINI : ");
printf("nama1 --> %s\n", nama1);
printf("nama2 --> %s\n", nama2);
}
?
?
namahari
“Selasa”,
“Rabu”,
“Kamis”,
“Jumat”,
“Sabtu”,
“Minggu”};
alamat alamat
nilai
ptr1 ptr1
Untuk membentuk rantai pointer seperti pada gambar di atas, pendeklarasian yang
diperlukan berupa
int var_x;
int *ptr1;
int **ptr2;
ptr1 = &var_x;
141
ptr2 = &ptr1;
Contoh berikut memberikan gambaran cara pengaksesan nilai pada var_x melalui
pointer ptr2 dan ptr1.
#include <stdio.h>
main()
{
int var_x = 273;
int *ptr1;
int **ptr2;
ptr1 = &var_x;
ptr2 = &ptr1;
Contoh eksekusi :
Nilai var_x = 273
Nilai var_x = 273
*x = *x + 2;
*y = *y + 2;
}
Fungsi di atas dimaksudkan agar kalau dipanggil, variabel yang berkenaan dengan
parameter aktual dapat diubah nilainya, masing-masing dinaikkan sebesar 2. Contoh
pemanggilan :
naikkan_nilai(&a, &b);
Perhatikan, dalam hal ini variabel a dan b harus ditulis diawali operator alamat (&) yang
berarti menyatakan alamat variabel, sebab parameter fungsi dalam pendefinisian berupa
pointer.
/* Program : argptr.c
Fungsi dengan argumen berupa pointer */
#include <stdio.h>
main()
{
int a = 3, b = 7;
naikkan_nilai(&a, &b);
printf("KINI : a = %d b = %d\n", a, b);
}
void naikkan_nilai(int *x, int *y)
143
{
*x = *x + 2;
*y = *y + 2;
}
Contoh eksekusi :
Semula : a = 3 b = 7
Kini : a = 5 b = 9
char *nama_bulan()
menyatakan bahwa keluaran fungsi nama_bulan() berupa pointer yang
menunjuk ke obyek char (atau string).
Dalam fungsi nama_bulan(), mula-mula array bernama bulan dideklarasikan dan
sekaligus diinisialisasi agar menunjuk sejumlah string yang menyatakan nama bulan.
Di bagian akhir fungsi, pernyataan
return ( (n<1 || n>12) ? bulan[0] : bulan[n] );
menyatakan bahwa hasil fungsi berupa pointer yang menunjuk ke
string “Kode bulan salah” (bulan[0]) jika masukan fungsi n<1 atau n>12
bulan[n] untuk n yang terletak antara 1 sampai dengan 12.
#include <stdio.h>
main()
{
int bl;
char *pch;
145
Kesimpulan
• Tipe variabel pointer adalah tipe variabel yang berisi alamat dari variabel yang
sebenarnya.
• Tipe variabel pointer harus sama dengan tipe varibel yang ditunjuk.
• Hubungan antara pointer dan array pada C sangatlah erat, sebab sesungguhnya array
secara internal akan diterjemahkan dalam bentuk pointer
• Varibel pointer bisa berupa string, array atau tipe variabel yang lainnya.
• Suatu pointer bisa saja menunjuk ke pointer lain (pointer to pointer)
• Variabel pointer bisa digunakan sebagai parameter dalam sebuah fungsi, sebagaimana
juga bisa dijadikan sebagai nilai balik (return value) dari sebuah fungsi.
146
Latihan :
Buatlah potongan program untuk soal-soal di bawah ini
#include <stdio.h>
main()
{
int z = 20, s = 30; int
*pz, *ps;
pz = &z;
ps = &s;
*pz += *ps;
#include <stdio.h>
main() { char c = 'Q';
char *char_pointer = &c;
Tujuan :
1. Menjelaskan cara mendeklarasikan struktur
2. Menjelaskan cara menginisialisasi struktur
3. Menjelaskan cara mengakses elemen struktur
4. Menjelaskan pemebentukan array dari struktur (array of struct)
5. Menjelaskan tentang hubungan antara struktur dengan fungsi
6. Menjelaskan tentang hubungan antara struktur dengan pointer
Struktur adalah pengelompokan variabel-variabel yang bernaung dalam satu nama yang
sama. Berbeda dengan array yang berisi kumpulan variabel-variabel yang bertipe sama
dalam satu nama, maka suatu struktur dapat terdiri atas variabel-variabel yang berbeda
tipenya dalam satu nama struktur. Struktur biasa dipakai untuk mengelompokkan beberapa
informasi yang berkaitan menjadi sebuah kesatuan (dalam bahasa PASCAL, struktur disebut
dengan record).
Variabel-variabel yang membentuk suatu struktur, selanjutnya disebut sebagai elemen
dari struktur atau field. Dengan demikian dimungkinkan suatu struktur dapat berisi elemen-
elemen data berbeda tipe seperti char, int, float, double, dan lain-lain. Contoh sebuah struktur
adalah informasi data tanggal (date) yang berisi :
- day
- month, dan
- year
145
146
struct date {
int month, day, year;
};
yang mendefinisikan sebuah tipe data struktur bernama date yang memiliki tiga buah elemen
(field) berupa : - day
- month - year
struct date
mengawali dan { int month; masing-masing
mengakhiriint day; disebut field atau elemen-elemen
int year; elemen struktur
struktu };
r
Gambar 9.1 Pendefinisian tipe struktur
Untuk mendeklarasikan sebuah variabel today yang bertipe struktur date pernyataan
yang diperlukan adalah sebagai berikut:
struct date {
int month, day, year;
};
struct person {
char name[30];
struct date birthday;
};
student month
birthdayday
year
variabel_struktur.nama_field
Untuk memberikan data nama ke field name dari variabel student di atas, maka pernyataan
yang diperlukan misalnya adalah :
Pada pernyataan di atas, student.name dapat dibaca sebagai "field name dari student".
Contoh berikut merupakan instruksi untuk mengisikan data pada field birthday :
student.birthday.day = 10;
Sedangkan untuk mendapatkan isi suatu field dari variabel struktur, contohnya :
tgl = student.birthday.day;
148
puts(student.name);
Contoh pertama merupakan instruksi untuk memberikan isi dari field day ke variabel tgl.
Sedangkan contoh kedua merupakan instruksi untuk menampilkan isi dari field name.
Program berikut merupakan contoh yang melibatkan variabel struktur. Mulamula field dari
struktur diisi dengan suatu data, kemudian isinya ditampilkan.
#include <stdio.h>
#include <string.h>
#include <stdio.h>
main()
{
struct zodiak { char
nama[11]; int
tgl_awal; int
bln_awal; int
tgl_akhir; int
bln_akhir;
};
Contoh eksekusi :
#define MAKS 20
.
.
.
struct date { /* definisi dari tipe date */
int month; int day;
int year;
};
struct person { /* definisi dari tipe person */
char name[30]; struct date birthday;
};
yang artinya, mendeklarasikan array student yang memiliki elemen yang bertipe struct
person sebanyak MAKS. Setelah array student dideklarasikan, maka ruang yang
disediakan ditunjukkan dalam gambar 9.4 di bawah ini.
birthday
0
1
18
19
};
#include <stdio.h>
#define MAKS 20
main()
{
int i=0, sudah_benar, jml;
char lagi;
/* memasukkan data */
do {
printf("Name : ");
fgets(student[i].name, sizeof student[i].name, stdin);
i++;
/* menampilkan data */
printf("DATA SISWA\n");
for (i=0; i<jml; i++)
{
printf("%d. Name : %s", i+1, student[i].name);
printf(" Birthday : %d-%d-%d\n\n",
student[i].birthday.month, student[i].birthday.day,
student[i].birthday.year );
};
}
Contoh eksekusi :
Name : Salsabila
Birthday (mm-dd-yyyy) : 10-25-1979
Name : Wildan
Birthday (mm-dd-yyyy) : 4-16-1974
DATA SISWA
1. Name : Salsabila
Birthday : 10-25-1979
2. Name : Wildan
Birthday : 4-16-1974
#include <stdio.h>
main()
{
struct date { /* definisi lokal dari tipe date */ int
month; int day; int year;
} today;
Contoh eksekusi :
Tampak bahwa elemen dari struktur dilewatkan ke fungsi memakai bentuk pengaksesan
elemen struktur, berupa :
cetak_tanggal(today.month, today.day, today.year);
Apabila nilai suatu elemen struktur diharapkan akan diubah oleh fungsi, maka yang
dilewatkan haruslah berupa alamat dari elemen struktur (pass by reference). Untuk
keperluan ini, operator alamat ditempatkan di depan nama variabel struktur (bukan di depan
nama elemen struktur).
#include <stdio.h>
main()
{
struct koordinat {
int x; int y;
} posisi;
z = *a; *a
= *b;
*b = z;
}
Contoh eksekusi :
main()
{
struct date today;
cetak_tanggal(today);
}
void cetak_tanggal(struct date now)
{
static char *nama_bulan[] = {
"Wrong month", "January", "February", "March",
"April", "May", "June", "July", "August",
"September", "October", "November", "December"
};
printf("Todays date is %s %d, %d\n\n",
nama_bulan[now.month], now.day, now.year); }
Contoh eksekusi :
z = (*pos_xy).x;
(*pos_xy).x = (*pos_xy).y;
(*pos_xy).y = z;
}
menyatakan bahwa pos_xy adalah pointer yang menunjuk ke obyek bertipe struktur
koordinat. Adapun penulisan :
(*pos_xy).x
(*pos_xy).x
Ungkapan *pos_xy.x mempunyai makna yaitu : "yang ditunjuk oleh pos_xy.x " (sebab
operator titik mempunyai prioritas yang lebih tinggi daripada operator *).
#include <stdio.h>
struct koordinat
{ int x;
int y;
};
main()
{
struct koordinat posisi;
tukar_xy(&posisi);
z = (*pos_xy).x;
(*pos_xy).x = (*pos_xy).y;
(*pos_xy).y = z;
}
Contoh eksekusi :
Bentuk semacam :
(*pos_xy).x
pos_xy->x
Dalam C operator -> (berupa tanda minus - diikuti dengan tanda lebih dari >) disebut
sebagai operator panah. Dengan menggunakan operator panah, maka fungsi tukar_xy()
dalam program posisi2.c dapat ditulis menjadi
z = pos_xy->x; pos_xy->x
= pos_xy->y;
pos_xy->y = z;
}
Kesimpulan :
• Struktur adalah pengelompokan variabel-variabel yang bernaung dalam satu nama yang
sama, namun tipe datanya tidak harus sama.
159
Latihan :
Buatlah potongan program untuk soal-soal di bawah ini
3. Masukkan nilai 10 kepada field loop dari struktur sample yang bertipe struktur
record tsb.
4. Tampilkan ke layar (menggunakan fungsi printf()) string yang tersimpan dalam array
word dari struktur sample.
160
Tujuan :
1. Menjelaskan tentang tipe data union
2. Menjelaskan penggunaan bitfield
3. Menjelaskan tentang tipe data enumerasi
4. Menjelaskan penggunaan typedef
5. Menjelaskan penggunaan ternary operator
6. Menjelaskan tentang konversi tipe data (type casting)
10.1 Union
Pada C, union memungkinkan suatu lokasi memori ditempati oleh dua atau lebih
variabel yang bisa saja tipenya berlainan. Di bawah ini diberikan contoh pendefinisian tipe
union yang dinamakan sebagai bil_bulat, yang digunakan untuk menyatakan data bertipe
karakter atau integer.
union bil_bulat {
unsigned int di;
unsigned char dc[2];
};
Berikutnya, pendeklarasian suatu variabel union bernama bil_x yang bertipe bil_bulat
dilakukan dengan cara penulisan sebagai berikut
Catatan : Cara lain untuk mendefinisikan atau mendeklarasikan union adalah seperti pada
struktur.
162
161
Gambar 10.1 memperlihatkan di dan dc berbagi tempat pada lokasi yang sama (di dan dc[0]
mempunyai alamat yang sama)
dc[0]
dc[1] di
Gambar 10.1 Variabel bil_x yang bertipe union bil_bulat dalam memori
Dalam hal ini, kompiler dengan bijaksana akan menyediakan ruangan yang cukup
untuk menampung field atau elemen pada union yang membutuhkan memori paling besar.
Pada pendeklarasian variabel bil_x misalnya, memori yang ditempati variabel ini adalah 4
byte (yaitu ukuran dari tipe int).
Elemen dari sebuah union dapat diakses dalam bentuk sebagai berikut :
variabel_union.nama_elemen
misal : bil_x.di = 321; adalah contoh untuk mengisikan 321 ke elemen union bernama
di. Kalau dituliskan angka biner dari 321 = 101000001. Dengan pengisian nilai ini, maka
dc[0] akan bernilai byte ke-0 dari di, sedangkan dc[1] bernilai byte ke-1 dari di.
#include <stdio.h>
main()
{
union
{
unsigned int di;
unsigned char dc[2];
} bil_x; /* variabel union */
bil_x.di = 321;
}
Contoh eksekusi :
di = 321
dc[0] = 65 dc[1] = 1
Program di atas menjelaskan cara ntuk mengakses byte ke-0 atau byte ke-1 dari di, dc[0]
atau dc[1] yang digunakan.
1 65
Seperti halnya pada struktur, suatu variabel union dapat dilewatkan ke dalam suatu fungsi
sebagai parameter. Di bawah ini contoh program yang memberikan gambaran tentang cara
mengubah isi suatu variabel union melalui pemanggilan suatu fungsi. Dalam hal ini, yang
dilewatkan ke dalam fungsi berupa alamat dari variabel union.
#include <stdio.h>
union bil_bulat{
unsigned int di;
unsigned char dc[2]; /* definisi tipe union */
};
void beri_nilai(union bil_bulat *x); /*prototype fungsi */
main() {
union bil_bulat bil_x; /* deklarasi var union */
Contoh eksekusi :
di =
321
dc[0] = 65 dc[1] = 1
10.2 Bitfield
Suatu bit atau beberapa bit dalam sebuah data berukuran satu byte atau dua byte dapat
diakses dengan mudah melalui bitfield. Dengan cara ini, suatu bit atau beberapa bit dapat
diakses tanpa melibatkan operator pemanipulasi bit (seperti &, |). Selain itu, satu atau dua
byte memori dapat dipakai untuk menyimpan sejumlah informasi.
Sebagai contoh, untuk memperoleh informasi masing-masing bit dari suatu data satu byte,
penulisan medan bit berupa
struct info_byte
{ unsigned bit0:1;
unsigned bit1:1;
unsigned bit2:1;
unsigned bit3:1;
unsigned bit4:1;
unsigned bit5:1;
unsigned bit6:1;
unsigned bit7:1;
};
Jika disajikan dalam bentuk gambar, gambaran suatu struktur yang memiliki tipe seperti di
atas adalah sebagai berikut :
bit 7 6 5 4 3 2 1 0
bbbbbbbb iiiiiiii
165
tttttttt 76543210
Gambar 10.2 Susunan bit dari memori sebuah data bertipe info_byte
Catatan : sebuah variabel bitfield haruslah dideklarasikan berupa salah satu di antara int,
unsigned dan signed
Contoh berikut memberikan gambaran tentang cara memberikan nilai kepada variabel
struktur yang mengandung elemen berupa bitfield, dan cara mengakses setiap nilai dari
bitfield.
#include <stdio.h>
main()
{
struct info_byte /* definisi tipe bitfield */
{
166
Contoh eksekusi :
scanf(“%c”, &ascii.karakter);
dan user memasukkan karakter : ‘A’ , berarti nilai ascii.karakter = ‘A’. Maka hal itu
memberikan efek elemen byte juga akan bernilai seperti karakter, sebab byte dan karakter
berbagi data pada memori yang sama. Namun, walaupun adanya sifat demikian, pernyataan
:
ascii.byte = 'A';
167
akan dianggap salah (saat kompilasi), sebab suatu variabel struktur yang mengandung
elemen bitfield memang tidak diijinkan untuk diberi nilai secara langsung. Pengaksesan nilai
dapat dilakukan melalui variabel bitfield, misalnya :
printf("%d", ascii.byte.bit7);
struct data_gambar
{
unsigned piksel1:2;
unsigned piksel2:2;
unsigned piksel3:2;
unsigned piksel4:2;
} koord;
Pada contoh di atas, variabel koord yang bertipe data_gambar akan menempati memori 1
byte (8 bit) dengan 4 informasi terkandung di dalamnya (masing-masing 2 bit), atau
memegang nilai bulat antara 0 sampai dengan 3 (22 – 1).
Untuk memberikan nilai kepada piksel1 misalnya, bisa digunakan pernyataan sebagai
berikut :
koord.piksel1 = 3;
yang mengisikan 3 ke dalam bitfield
tersebut.
Bitfield biasanya dipakai untuk menghemat memori. Misalnya ada dua informasi dengan
keterangan sebagai berikut :
informasi pertama (info_x) memiliki kemungkinan nilai bilangan bulat antara 0 sampai
dengan 3, dan
informasi kedua (info_y) memiliki kemungkinan nilai bilangan bulat 0 atau 1 saja.
Seandainya kedua informasi itu disimpan dalam memori (secara terpisah) sebagai tipe char,
maka akan diperlukan total memori sebesar 2 byte. Namun jika disajikan dalam bentuk
168
bitfield, memori yang dibutuhkan cukup 1 byte. Dalam hal ini info_x akan dinyatakan dalam
2 bit dan info_y dinyatakan dalam 1 bit. Penuangan deklarasinya adalah sebagai berikut :
struct info
{
unsigned info_x:2;
unsigned info_y:1;
} status;
atau
struct info
{
unsigned info_x:2;
unsigned info_y:1;
unsigned :5;
} status;
unsigned :5;
fungsinya hanya untuk memperjelas bahwa total bit dari bitfield adalah 8 bit (1 byte).
Perhatikan, bahwa karena 5 bit terakhir tidak diperlukan, maka nama bitfield boleh tidak
disertakan. Kalaupun mau diberi nama (misalnya : kosong), maka bentuk deklarasinya
adalah :
struct info
{
unsigned info_x:2;
unsigned info_y:1;
unsigned kosong:5;
} status;
main()
{
/* definisi tipe bitfield */
struct info
{
unsigned info_x:2;
unsigned info_y:1;
unsigned kosong:5; /* bisa dihilangkan */
169
} status;
status.info_x = 3;
status.info_y = 1;
Contoh eksekusi :
info_x = 3
info_y = 1
10.3 Enumerasi
Tipe enumerasi merupakan himpunan dari konstanta integer yang diberi nama. Contoh
enumerasi yaitu berupa jenis kelamin manusia yang berupa
pria, wanita
Dalam C, suatu tipe data enumerasi dideklarasikan dengan bentuk :
enum nama_tipe_enumerasi {
konstanta_1, konstanta_2,…
} variabel_1, …, variabel_n;
#include <stdio.h>
main()
{
enum manusia { /* definsi tipe */
pria, wanita
170
};
enum manusia jns_kelamin; /*
deklarasi var */
Isi jns_kelamin = 0
Isi jns_kelamin = 1
degnan sendirinya pria merupakan konstanta dengan nilai sama dengan 0, sedangkan wanita
bernilai 1. Sehingga pernyataan
jns_kelamin = pria;
#include <stdio.h>
main()
{
/* definisi tipe data enumerasi */
enum data_hari {senin, selasa, rabu, kamis,
jumat, sabtu, minggu}; /* keterangan nama hari
*/
static char str[][7] = {"SENIN", "SELASA", "RABU",
"KAMIS", "JUMAT", "SABTU", "MINGGU"};
int jam_kerja;
int total_jam = 0;
Contoh eksekusi :
Jika dikehendaki, nilai urutan sebuah enumerasi juga bisa dirubah (yang secara default akan
dimulai dari 0 dan naik satu demi satu berdasarkan urutan konstanta dalam pendefinisian).
Sehingga dengan mendefinisikan seperti berikut :
enum {
staff = 4, manajer, direktur
} jenjang_jab;
maka staff tidak lagi berupa nilai 0, melainkan berupa nilai 4. Dengan sendirinya, manajer
bernilai 5 dan direktur bernilai 6.
#include <stdio.h>
main()
{
/* definisi tipe data enumerasi */
enum {
staff = 4, manajer, direktur
} jenjang_jab;
Contoh eksekusi :
4
5
6
10.4 Typedef
Untuk kepentingan memperjelas dokumentasi program C, user bisa menamakan
suatu tipe data dengan pengenal (identifier) yang lebih memberi arti atau mudah diingat.
Caranya adalah dengan memakai typedef. Sebagai contoh pengenal BYTE dapat digunakan
untuk menyatakan unsigned char.
173
Contoh :
karakter a;
Contoh tsb menyatakan bahwa BYTE identik dengan unsigned char. Sesudah pendefinisian
tersebut, BYTE dapat digunakan untuk mendeklarasikan variabel atau jenis parameter fungsi,
bahkan juga keluaran fungsi. Misalnya :
BYTE kode;
untuk mendeklarasikan variabel kode agar bertipe BYTE (atau unsigned char) . Contoh lain
:
BYTE beri_nilai_awal(void);
#include <stdio.h>
main()
{
BYTE kode; /* deklarasi variabel karakter */
kode = beri_nilai_awal(); printf("Isi kode = %u\n",
kode);
}
BYTE beri_nilai_awal(void)
{
return(143);
174
Contoh eksekusi :
salah
benar
Catatan : penulisan kondisi (nilai1 < nilai2) sebenarnya bisa ditulis menjadi nilai1 < nilai2
tanpa menyertakan kurung, disebabkan operator > memiliki prioritas lebih tinggi
daripada operator kondisi (?). Pemberian tanda kurung hanya untuk menambah
kejelasan.
Pernyataan :
#include <stdio.h>
main()
{
float nilai1, nilai2, max;
176
Contoh eksekusi :
Masukkan dua buah nilai : 9 10.5
Nilai terbesar = 10.5
(tipe) ungkapan
(float) x/2;
Perbedaan penggunaan type cast dengan yang tidak menggunakannya dapat dilihat pada
contoh program di bawah ini.
#include <stdio.h>
main()
{
int x = 21;
float y;
177
y = x/2;
printf("y = x/2 = %f\n", y);
y = (float) x/2;
printf("y = (float) x/2 = %f\n", y);
y = (float) (x/2);
printf("y = (float) (x/2) = %f\n", y);
}
Contoh eksekusi :
y = x/2 = 10.000000
y = (float) x/2 = 10.500000
y = (float) (x/2) = 10.000000
Tampak bahwa jika ungkapan y = x/2 tidak menggunakan type cast, maka variabel y
akan bernilai 10.000000 untuk x = 21, tetapi jika ditulis y = (float) x/2, maka didapat
nilai y = 10.500000.
Adanya (float) x/2 mengakibatkan x bertipe float. Berdasarkan sifat konversi, jika salah
satu operand bertipe real, dengan sendirinya yang lain juga akan bertipe real.
Oleh karena itu ungkapan (float) x/2 menghasilkan pembagian real.
Pada ungkapan y = x/2, baik x maupun 2 bertipe integer, maka yang terjadi adalah operasi
pembagian bulat, baru kemudian hasil pembagiannya dikonversikan secara otomatis
(karena adanya tanda assignment '=') dengan tipe data dari y, sehingga y =
10.000000.
Penulisan (float) x/2 berbeda dengan (float) (x/2). Pada (float) (x/2), yang
dikonversikan ke float adalah hasil dari x/2, sedangkan operasi pembagian x/2 sendiri
dianggap sebagai operasi pembagian bulat.
Kesimpulan :
• Union memungkinkan suatu lokasi memori dapat ditempati oleh dua atau lebih
variabel yang bisa saja tipenya berlainan.
• Seperti halnya pada struktur, suatu variabel union dapat dilewatkan ke dalam suatu
fungsi sebagai parameter.
• Suatu bit atau beberapa bit dalam sebuah data berukuran satu byte atau dua byte dapat
diakses dengan mudah melalui bitfield. Dengan cara ini, suatu bit atau beberapa bit
178
dapat diakses tanpa melibatkan operator pemanipulasi bit (seperti &, |). Selain itu,
satu atau dua byte memori dapat dipakai untuk menyimpan sejumlah informasi.
• Tipe enumerasi merupakan himpunan dari konstanta integer yang diberi nama.
• Untuk kepentingan memperjelas dokumentasi program C, user bisa menamakan suatu
tipe data dengan pengenal (identifier) yang lebih memberi arti atau mudah diingat
dengan memakai typedef.
• C menyediakan sebuah operator yang tergolong sebagai operator ternary, yakni
operator yang memiliki tiga buah operand. Operator tersebut dinamakan sebagai
operator kondisi, yang merupakan cara lain dari if-else untuk penyeleksian kondisi.
• Type cast merupakan upaya untuk mengkonversikan suatu tipe data menjadi tipe yang
lain.
Latihan :
Tujuan :
1. Menjelaskan tentang struktur file
2. Menjelaskan tentang tahap-tahap operasi pada file
3. Menjelaskan tentang fungsi untuk penyimpanan dan pembacaan file per-karakter
4. Menjelaskan tentang file biner dan file teks
5. Menjelaskan tentang operasi penyimpanan dan pembacaan file per-int
6. Menjelaskan tentang operasi penyimpanan dan pembacaan file per-blok
7. Menjelaskan cara membaca dan menyimpan data string pada file
8. Menjelaskan cara mengakses file biner secara acak
9. Menjelaskan cara menghapus file
10. Menjelaskan cara mengganti nama file
FILE
RECORD … RECORD
BYTE … BYTE
)
(8 BIT
179
11.2 Tahapan Operasi File
Operasi pada file pada dasarnya meliputi tiga tahapan, yaitu :
1. Membuka/mengaktifkan file
2. Melaksanakan proses file
3. Menutup file
dengan :
namafile berupa nama dari file yang akan diaktifkan
mode berupa jenis operasi yang akan dilakukan terhadap file
prototipe ada pada file stdio.h
Jenis operasi file dapat berupa salah satu di antara mode berikut :
r menyatakan file hanya akan dibaca.
Dalam hal ini, file yang akan diproses haruslah sudah ada dalam disk pada current
directory.
w menyatakan bahwa file baru diciptakan. Selanjutnya operasi yang akan dilakukan
terhadap file adalah operasi perekaman data. Seandainya file tersebut sudah ada dalam
disk, isinya yang lama akan terhapus.
a untuk membuka file yang sudah ada dalam disk, dan operasi yang akan dilakukan
adalah penambahan data pada file. Data baru akan ditempatkan di bagian belakang dari
file. Seandainya file belum ada, secara otomatis file akan diciptakan terlebih dahulu.
r+ untuk membuka file yang sudah ada, dan operasi yang akan dilakukan berupa
pembacaan serta penulisan.
w+ untuk membuka file dengan tujuan untuk pembacaan atau penulisan. Jika file sudah
ada, isinya akan dihapus.
a+ untuk membuka file, dengan operasi yang dapat dilakukan berupa perekaman
maupun pembacaan. Jika file sudah ada, isinya tak akan dihapus.
181
Keluaran fungsi fopen() berupa pointer yang menunjuk ke tipe FILE (pointer to FILE), yaitu
tipe struktur yang definisinya ada pada stdio.h (oleh karena itu program yang menggunakan
fopen() harus melibatkan file stdio.h).
Berhasil tidaknya operasi pengaktifan file dapat dilihat pada keluaran fungsi fopen(). Jika
keluaran fungsi berupa NULL (suatu makro yang didefinisikan pada file stdio.h), berarti
operasi pengaktifan file gagal. Kejadian seperti ini bisa terjadi misalnya saat membuka file
dengan mode “r” ternyata file yang dibuka tidak ada dalam disk.
Contoh pemakaian fungsi fopen() :
pf = fopen(“COBA.TXT”, “w”);
FILE *pf;
Informasi file pf
COBA.TXT
pointer-ke-FILE
struct FILE
Mula-mula pf diisi dengan keluaran dari fungsi fopen(). Seandainya nilainya adalah
NULL (berarti operasi pengaktifan gagal), maka
pada layar ditampilkan tulisan : File tidak dapat diciptakan !
program dihentikan (selesai).
int fcloseall(void);
Fungsi ini menghasilkan nilai EOF (EOF didefinisikan pada stdio.h, yaitu bernilai –1) jika
terjadi kegagalan. Sedangkan bila berhasil, keluaran fungsi berupa jumlah file yang ditutup.
dengan ptr_file adalah pointer-ke-FILE yang berisi keluaran dari fopen(), dan kar berupa
karakter yang akan disimpan dalam file. Sekalipun kar bertipe int (2 byte), sebenarnya hanya
byte terendah dari kar yang akan disimpan ke dalam file. Byte tertinggi tak ikut disimpan.
Seandainya operasi fputc() berjalan dengan sempurna, keluaran fungsi sama dengan
nilai kar. Bila tak berhasil melaksanakan penyimpanan, keluaran fungsi berupa EOF (-1).
Contoh program untuk menciptakan file dan digunakan untuk menyimpan sejumlah karakter
:
#include <stdio.h>
#include <stdlib.h>
main()
{
FILE *pf; /* Pointer-ke-FILE */ char kar;
/* Ciptakan file */
if ((pf = fopen("COBA.TXT","w")) == NULL)
{
printf("file tak dapat diciptakan!\r\n");
exit(1); /* selesai */
}
Contoh eksekusi :
Program mula-mula menciptakan dan membuka file melalui pemanggilan fungsi fopen(),
dengan mode file “w”. Kalau keluaran fungsi bernilai NULL, program dihentikan melalui
exit( ). Kalau file COBA.TXT berhasil dibuka, maka pernyataan
akan dijalankan, yang memungkinkan untuk memasukkan sejumlah karakter, sampai tombol
ENTER ditekan (ENTER tidak ikut disimpan dalam file). Jika tombol ENTER ditekan, file
akan ditutup dan eksekusi program selesai. Sedangkan file COBA.TXT yang dihasilkan oleh
program di atas merupakan file teks, sehingga isinya bisa dilihat dengan menggunakan
bantuan sebuah teks editor misalnya Notepad.
Keluaran fungsi berupa nilai bertipe int dari sebuah karakter yang dibaca dari file. Jika akhir
file ditemukan atau terjadi kegagalan membaca, keluaran fungsi berupa EOF.
Program berikut digunakan untuk membaca isi file COBA.TXT dengan langkah-langkah
sebagai berikut :
1. Buka file COBA.TXT dengan mode “r”
Jika tidak berhasil dibuka maka
- beri keterangan pada layar bahwa file tak ada -
selesai
185
#include <stdio.h>
#include <stdlib.h>
main()
{
FILE *pf; char
kar;
printf("\n");
fclose(pf); /* tutup file */
}
Contoh eksekusi :
Sedangkan file teks merupakan file yang pola penyimpanan datanya dalam bentuk
karakter. Bilangan bertipe int misalnya, bisa saja menempati ruang 1 byte, 2 byte atau lebih
bergantung kepada nilai dari bilangannya. Sebagai contoh, bilangan 54 akan disimpan dalam
2 byte (berupa karakter 5 dan 4), tetapi bilangan 123 akan disimpan dalam 3 byte. File seperti
ini bisa dilihat langsung dengan perintah TYPE melalui prompt DOS atau memakai editor
teks (seperti Notepad).
File teks biasanya dipakai untuk menyimpan data bertipe karakter atau string.
Sedangkan file biner dipakai untuk menyimpan data bilangan atau data kompleks, seperti
struktur (struct).
Penambahan yang perlu dilakukan untuk menentukan mode teks atau mode biner
berupa :
t untuk mode teks b untuk mode biner Contoh :
"rt" Berarti mode file adalah teks dan file hendak dibaca
"rt+" Berarti mode file adalah teks dan file bisa dibaca dan ditulisi.
Bentuk penulisan yang lain (tetapi maknanya sama) : "r+t" "rb"
Catatan :
Jika pada mode file tidak terdapat karakter t atau b, mode file akan ditentukan oleh
variabel global bernama _fmode (deklarasinya ada pada file fcntl.h). Jika _fmode tidak
dilibatkan dalam program, maka mode file yang tak mengandung t atau b akan
diperlakukan sebagai file teks (secara default).
Variabel _fmode bisa diisi dengan O_BINARY untuk menyatakan file biner, atau
O_TEXT untuk menyatakan file teks. Contoh :
_fmode = O_BINARY; pf =
fopen("TEST1", "r");
#include <stdio.h>
#include <stdlib.h>
main(
)
{
FILE *pf; /* ptr-ke-FILE */ int nilai,
sudah_benar; char jawab;
do
{
jawab = getchar(); /* baca jawaban dr keyboard */
sudah_benar = ((jawab == 'Y') || (jawab == 'y')
|| (jawab == 'T') || (jawab == 't'));
} while(! sudah_benar);
}
while (jawab == 'y'|| jawab == 'Y');
188
Program yang digunakan untuk menampilkan isi file BILANGAN.DAT pada dasarnya
sama dengan program fgetc.c yang menampilkan isi file teks COBA.TXT di atas. Hanya
saja, untuk mendeteksi akhir dari file, diperlukan makro bernama feof(), yang memiliki
bentuk deklarasi
#include <stdio.h>
#include <stdlib.h>
main()
{
FILE *pf; /* ptr ke file */
int nilai, nomor = 0;
/* Buka file biner untuk dibaca */
if((pf=fopen("BILANGAN.DAT","rb")) == NULL)
{
printf("File gagal dibuka.\n");
exit(1);
}
189
Contoh eksekusi :
dengan :
buffer adalah
- pointer yang menunjuk ke daerah memori yang akan ditempati data dari file disk
(untuk fread()), atau
- pointer yang menunjuk ke daerah memori yang akan berisi data yang akan disimpan
ke file disk (untuk fwrite()).
jum_byte menyatakan jumlah byte yang akan dibaca atau disimpan.
190
n menentukan banyaknya blok data berukuran jum_byte yang akan ditulis atau
dibaca. ptr_file berupa pointer-ke-FILE yang berisi nilai keluaran dari fopen().
Program berikut ini memberikan contoh penyimpanan data bertipe struktur ke dalam file
disk bernama DAFBUKU.DAT.
#include <stdio.h>
#include <stdlib.h>
main()
{
FILE *f_struktur; char
jawaban;
int sudah_benar;
struct { char
judul[26]; char
pengarang[20]; int
jumlah;
} buku; /* variabel buku bertipe struktur */
/* Buka file */
if((f_struktur = fopen("DAFBUKU.DAT", "wb")) == NULL)
{
printf("File tidak dapat diciptakan !\n");
exit(1);
}
do {
fflush(stdin); /* Hapus isi penampung keyboard */
printf("Judul buku : "); gets(buku.judul);
do {
191
jawaban = getchar();
sudah_benar = ((jawaban == 'Y') || (jawaban ==
'y')||(jawaban == 'T') || (jawaban == 't'));
} while(!sudah_benar);
printf("\n");
Contoh eksekusi :
Pada program di atas, instruksi untuk menyimpan sebuah data bertipe struct ke file adalah
yang menyatakan data sebanyak 1 x ukuran variabel struct buku (dalam satuan byte) dari
lokasi buku (dinyatakan dengan &buku) disimpan dalam file f_struktur (nama filenya
adalah DAFBUKU.DAT). Untuk membaca data yang ada pada file DAFBUKU.DAT,
programnya adalah sbb :
#include <stdio.h>
#include <stdlib.h>
192
main()
{
FILE *f_struktur;
int i=1;
struct { char
judul[30]; char
pengarang[30]; int
jumlah;
} buku; /* variabel buku bertipe struktur */
/* Buka file */
if((f_struktur = fopen("DAFBUKU.DAT", "rb")) == NULL)
{
printf("File tidak dapat dibuka !\n");
exit(1);
}
printf("\n");
fclose(f_struktur); /* Tutup file */
}
Contoh eksekusi :
Keluaran fungsi :
untuk fputs(): - Jika penyimpanan berhasil dilaksanakan, hasilnya berupa karakter yang
terakhir ditulis ke file.
- Jika gagal, hasilnya berupa EOF.
untuk fgets() : - Jika pembacaan berhasil dilaksanakan, hasilnya berupa pointer yang
menunjuk string yang ditunjuk oleh str.
- Jika gagal, hasilnya berupa NULL.
Catatan :
Pada saat menyimpan string ke file, fputs() tidak menambahkan karakter baris-baru ('\n')
dengan sendirinya, dan karakter null tidak ikut disimpan.
Pada saat pembacaan dengan fgets(), jika string yang dibaca mengandung karakter baris
baru (CR/LF), hanya karakter LF yang akan disertakan pada string. Secara otomatis
string akan diakhiri dengan karakter null Baik fgets() maupun fputs() digunakan untuk
file teks.
Perhatikan program-program di bawah ini :
#include <stdio.h>
#include <stdlib.h>
main(
)
{
FILE *f_teks; char
string[PANJANG]; char
namafile[65];
fclose(f_teks);
}
Contoh eksekusi :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
main()
{
FILE *pf_input, *pf_output; char
string[PANJANG];
char namafile_inp[65], namafile_out[65];
195
fcloseall();
Contoh eksekusi :
dengan :
ptr_file adalah pointer yang berasal dari keluaran fopen()
offset menyatakan jumlah byte terhadap posisi
posisi dapat diisi dengan salah satu nilai yang tertera pada tabel 11.1
Kegunaan fungsi fseek() yaitu untuk menempatkan penunjuk file ke suatu lokasi dalam file,
berdasarkan offset dan posisi.
Tabel 11.1 Konstanta untuk menentukan posisi pada pengaksesan file secara acak
Catatan :
Konstanta simbolis SEEK_SET, SEEK_CUR dan SEEK_END didefinisikan pada file
stdio.h
Prototipe fseek() ada pada stdio.h
Beberapa contoh :
(1) fseek(pf, 3, SEEK_SET);
197
Pernyataan seperti ini akan menempatkan penunjuk file ke posisi 3 byte sesudah awal file
(SEEK_SET).
posisi semula
penunjuk file posisi kini penunjuk file
3 byte terhadap
posisi semula
#include <stdio.h>
#include <stdlib.h>
main()
{
struct { char
judul[30]; char
pengarang[30]; int
jumlah;
} buku; /* variabel buku bertipe struktur */
/* Buka file */
if((pf = fopen("DAFBUKU.DAT", "rb")) == NULL)
{
printf("File tidak dapat dibuka !\n"); exit(1);
}
do {
i = 1;
printf("Nomor record dr data yg mau ditampilkan : ");
scanf("%d", &no_record);
printf("\n");
fclose(pf); /* Tutup file */
}
Contoh eksekusi :
Mula-mula program menanyakan nomor record dari data yang ingin ditampilkan. Selanjutnya
enunjuk file ditempatkan pada posisi data yang akan ditampilkan, melalui instruksi
Langkah berikutnya, membaca data file dengan menggunakan fread(). Kalau keluaran
fread() bernilai 0, maka di layar akan dimunculkan pesan : "Nomor record tidak
dikenali!"
Kegunaan fseek() selain untuk membaca data secara random, juga memungkinkan untuk
mengubah data secara acak, seperti pada program di bawah ini.
#include <stdio.h>
200
#include <stdlib.h>
#define SATU_RECORD 1
main()
{
struct { char
judul[30]; char
pengarang[30]; int
jumlah;
} buku; /* variabel buku bertipe struktur */
if(hasil_baca == 0)
printf("Nomor record tdk dikenali!\n");
else
{
printf("\n%-30s %-30s %s\n\n","Judul Buku", "Nama
Pengarang", "Jumlah"); printf("%-30s %-30s %4d\n\n",
buku.judul,
buku.pengarang, buku.jumlah);
/* Rekam ulang */
fwrite(&buku, sizeof(buku), SATU_RECORD, pf);
}
printf("\n");
fclose(pf); /* Tutup file */
}
Contoh eksekusi :
Proses penggantian data record dilakukan dengan mula-mula menempatkan penunjuk file
pada posisi dari data yang akan diganti. Selanjutnya data dibaca (dengan fread()), dan akan
ditampilkan di layar. Setelah data jumlah buku yang baru dimasukkan dari keyboard,
penunjuk file ditempatkan kembali ke posisi tempat data yang dibaca tadi. Kemudian data
baru (satu record) direkam ulang dengan fwrite().
dengan namafile adalah pointer yang menunjuk ke nama file yang akan dihapus.
Fungsi ini menghasilkan keluaran berupa nilai nol bila operasi penghapusan file berhasil
dilaksanakan. Kalu terjadi kegagalan, keluaran fungsi berupa selain nol. Prototipe dari
fungsi ini ada pada stdio.h
#include <stdio.h>
#include <stdlib.h>
#define PJG 65
main()
{
int kode; char
namafile[PJG];
else
printf("Gagal dalam menghapus file\n");
}
Contoh eksekusi :
Jika operasi penggantian nama file lama menjadi nama file baru ini berhasil, maka keluaran
fungsi berupa nol. Jika terjadi kegagalan, keluaran fungsi berupa selain nol. Prototipe dari
fungsi ini ada pada file stdio.h
#include <stdio.h>
#include <stdlib.h>
#define PJG 65
main()
{ int kode;
char namafilelama[PJG], namafilebaru[PJG];
Kesimpulan :
• File merupakan organisasi dari sejumlah record. Masing-masing record dapat terdiri
atas satu atau beberapa field dan setiap field terdiri atas satu atau beberapa byte.
Adapun byte merupakan susunan dari 8 bit.
• Operasi pada file pada dasarnya meliputi tiga tahapan, yaitu :
a. Membuka/mengaktifkan file
b. Melaksanakan proses file
c. Menutup file
• Sebelum file dapat diakses (dibaca atau ditulisi), mula-mula file haruslah diaktifkan
terlebih dahulu dengan menggunakan fungsi fopen().
• Untuk menutup file, fungsi yang digunakan adalah fclose().
204
• Sebuah karakter dapat disimpan dalam file dengan menggunakan fungsi fputc().
• Untuk melihat isi file digunakan fungsi fgetc(), yang digunakan untuk pembacaan per
karakter dari isi file.
• File biner adalah file yang pola penyimpanan di dalam disk berbentuk biner, yaitu
seperti bentuk pada memori RAM (komputer). Sedangkan file teks merupakan file
yang pola penyimpanan datanya dalam bentuk karakter.
• Untuk keperluan menyimpan atau membaca membaca file bertipe int, digunakan
fungsi _putw() dan _getw().
• Fungsi yang digunakan untuk menyimpan atau membaca data file dalam bentuk
kesatuan blok (sejumlah byte), misalnya untuk menyimpan data bertipe float atau data
bertipe struct adalah fread() dan fwrite().
• Dua fungsi yang dipakai untuk membaca data string pada file yaitu fgets() dan fputs().
• Untuk keperluan pengaksesan secara random, fungsi yang digunakan adalah fseek().
• Fungsi yang berguna untuk menghapus file yaitu remove().
• Untuk mengganti nama file, fungsi yang digunakan yaitu rename().
atihan :
Buatlah potongan program untuk soal-soal di bawah ini
4. Tuliskan potongan program dalam bahasa C untuk membaca satu baris karakter
(yang diakhiri dengan \n) dari input_file ke dalam array of char (misalkan nama
205
array-nya = buffer). Array buffer diakhiri dengan NULL setelah mencapai akhir
baris (membaca karakter \n). Terlebih dahulu deklarasikan semua variabel yang
dipakai.
5. Tuliskan pernyataan untuk menutup file (result.dat) yang terasosiasi dengan input_
file.
DAFTAR PUSTAKA
Kerninghan, Brian W., dan Ritchie, Dennis M., The C Programming Language, Prentice
Hall, Englewood Cliffs, New Jersey, 1988
Van Der Linden, Peter, Expert C Programming Deep C Secrets, Prentice Hall, Englewood
Cliffs, New Jersey,1994
vi