Pemrograman C-5

FUNGSI

Pada bab-bab sebelumnya secara tidak langsung sudah dipelajari dan diuji coba penggunaan fungsi, akan tetapi beberapa fungsi yang telah disajikan pada bab-bab sebelumnya mengembalikan hanya suatu nilai yang bertipe int. Apabila fungsi yang diciptakan dikehendaki tidak mengembalikan suatu nilai yang bertipe int mungkin bertipe float, double, char dan sebagainya, maka compiler harus diberitahu jenis data yang dikembalikan oleh fungsi tersebut. Sebagai contoh fungsi di bawah ini akan mengembalikan nilai rata-rata dengan menggunakan nilai bertipe float.

#include <stdio.h>

float average_value(int a, int b, int c)

{

return ((a + b + c) / 3.0);

}

void main (void)

{

printf (“The average of 100, 133, and 155 is %f\n”, average_value(100, 133, 155));

}

  1. Variabel Lokal

Compiler C memungkinkan pendeklarasian variabel di dalam fungsi yang dibuat. Variabel semacam ini disebut variabel local penamaan ini disebabkan karena nama dan nilai variabel yang diciptakan hanya dikenal pada fungsi tempat mereka didefinisikan.

Konsep dari variabel local ini dapat dilihat dari contoh program pendek di bawah ini.

#include <stdio.h>

void local_values(void)

{

int a = 1, b = 2, c = 3;

printf (“a contains %d b contains %d c contains %d\n”, a, b, c);

}

void main (void)

{

printf (“a contains %d b contains %d c contains %d\n”, a, b, c);

}

pada program pendek tersebut diatas fungsi local_values mendeklarasikan tiga variabel a, b dan c dan menugaskan angka 1,2 dan 3 ke variabel tersebut. Fungsi main mencoba menampilkan setiap nilai variabel, akan tetapi karena nama variabel tersebut hanya berlaku local untuk fungsi local_values, maka compiler akan menampilkan pesan kesalahan yang menyatakan bahwa symbol a, b, dan c belum didefinisikan.

Setiap kali fungsi local_values dipanggil, Compiler C akan mengalokasikan ruang stack untuk menampung variabel local a, b, c dan setiap kali fungsi tersebut berakhir, ruang stack tersebut dihapuskan, demikian pula nilai-nilai variabel yang tersimpan di dalamnya, sehingga ketika fungsi main akan mencoba menampilkan nilai variabel yang ada pada fungsi local_values dinyatakan belum didefinisikan karena sudah terhapus.

  1. Variabel Global

Seperti yang dipelajari pada sub bab sebelumnya bahwa variabel-variabel local adalah variabel yang didefinisikan di dalam sebuah fungsi yang nama dan kehadirannya hanya diketahui oleh fungsi tersebut. Selain variabel local yang yang telah dipelajari, compiler C juga memungkinkan untuk membuat variabel global yang nama dan kehadirannya diketahui oleh seluruh program yang diciptakan. Untuk memahami variabel global ini perhatikan program pendek di bawah ini.

#include <stdio.h>

int a = 1, b = 2, c = 3; // variabel global

void global_values(void)

{

printf (“a contains %d b contains %d c contains %d\n”, a, b, c);

}

void main (void)

{

global_values();

printf (“a contains %d b contains %d c contains %d\n”, a, b, c);

}

Apabila program tersebut di atas dikompilasi dan dieksekusi, fungsi global_values dan main akan menampilkan nilai variabel global. Perhatikan bahwa variabel tersebut dideklarasikan di luar semua fungsi. Apabila variabel global dideklarasikan semacam ini, semua fungsi di dalam program dapat menggunakan dan mengubah nilai variabel global terebut dengan menyebutkan nama variabel global. . Meskipun variabel global mula-mula terlihat sangat praktis, akan tetapi apabila salah dalam penggunaannya akan menimbulkan kesalahan yang sangat sulit untuk dilacak. Variabel global seringkali membuka kemungkinan munculnya lebih banyak kesalahan dari pada menguntungkan. Karena nilai sebuah variabel global dapat berubah pada lokasi mana saja di dalam program, maka kondisi ini membuat sangat sulit bagi pemrogram lain yang membaca program tersebut.untuk mencari setiap lokasi yang mengubah variabel global tersebut di dalam program , kemungkinan yang terjadi adalah pemrogram lain akan mengubah program tanpa benar-benar memahami dampak yang akan terjadi terhadap variabel global. Sebagai pegangan, fungsi-fungsi seharusnya hanya boleh mengubah variabel yang dilewatkan kepadanya sebagai parameter. dengan cara ini para pemrogram dapat mempelajari prototype fungsi tadi untuk dengan segera menentukan variabel mana yang telah diubah oleh sebuah fungsi. Untuk memahami variabel local dan variabel global cobalah latihan berikut ini dan amati apa yang terjadi.

LATIHAN 5.1

#include <stdio.h>

int count ; /*global count*/

main()

{

count = 10;

f1();

printf (“count in main() : %d\n”, count);

}

f1()

{

int count ; /*local count */

count = 100;

printf (“count in f1() : %d\n”, count);

}

LATIHAN 5.2

#include <stdio.h>

main()

{

int m, e;

m = 2;

e = 3;

printf (“ %d to the %d is %d\n”, m, e, power(m, e));

printf (“ 4 to the 5 is %d”, power(4,5));

}

/* Parametrized version of power */

power (int m, int e)

{

int temp;

temp = 1;

for ( ; e>0; e–) temp = temp + m;

return temp;

}

  1. Pemanggilan Berdasarkan Nilai dan Pemanggilan Berdasarkan Referensi (Call by Values & Call by reference)

Ketika sejumlah argument dikirimkan ke dalam sebuah fungsi, nilai-nilai argument tersebut pertama-tama disalin ke suatu wilayah khusus dalam memori yang dikenal dengan sebuah stack. Fungsi ini lalu menggunakan salinan tersebut untuk menjalankan operasi-operasinya sehingga nilai-nilai variabel dalam fungsi yang melakukan pemanggilan tersebut tetap tidak terpengaruhi. Cara pemanggilan fungsi seperti ini disebut dengan pemanggilan bersarkan nilai (call by value). Dengan menggunakan pemanggilan berdasarkan nilai, perubahan apapun yang dilakukan fungsi tersebut terhadap parameter hanya berlaku di dalam fungsi itu sendiri. Apabila fungsi tersebut berakhir, nilai-nilai variabel yang dilewatkan ke fungsi tidak berubah. Sebagai contoh program pendek berikut ini akan melewatkan 3 parameter (variabel a, b dan c) kepada fungsi display_and_change. Pada gilirannya fungsi tersebut lalu mengembalikan nilai-nilai ditambah dengan 100, dan kemudian menampilkan hasilnya. Karena compiler C menggunakan pemanggilan berdasarkan nilai, maka nilai variabel tersebut tidak berubah.

Latihan 5.3

#include <stdio.h>

void display_and_change (int first, int second, ind third)

{

printf(“Original function values %d %d %d\n”, first, second, third);

first += 100;

second +=100;

third += 100;

printf (“Ending function values %d %d %d\n”, first, second, third);

}

void main(void)

{

int a = 1, b = 2, c = 3;

display_and_change (a, b, c);

printf (“Ending values in main %d %d %d\n”, a, b, c);

}

Perhatikan keluaran dari program pendek tersebut setelah anda kompilasi, maka apabila tidak terdapat kesalahan sintaks, maka keluaran yang dihasilkan adalah sebagai berikut :

Original function values 1 2 3

Ending Function values 101 102 103

Ending values in main 1 2 3

Sebagaimana dapat dilihat pada keluaran diatas, perubahan yang dilakukan terhadap fungsi membuat variabel tersebut hanya dapat dilihat di dalam fungsi itu. Pada saat fungsi berakhir, variabel di dalam main tidak dirubah seperti semula.

Seperti terlihat pada contoh diatas secara default compiler C menggunakan pemanggilan berdasarkan nilai untuk melewatkan parameter-parameter fungsi. Akibatnya perubahan apapun terhadap nilai parameter hanya berlaku didalam fungsi itu sendiri. Pada saat fungsi tersebut berakhir, nilai variabel yang dilewatkan kepada fungsi tersebut tidak berubah. Kondisi tersebut disebabkan karena pada saat melewatkan parameter sebuah fungsi, compiler C menempatkan nilai-nilai yang bersangkutan ke stack. Pada kasus variabel a, b, c, stack tersebut berisi nilai-nilai 1, 2 dan 3. Pada saat fungsi tersebut mengakses nilai-nilai variabel, fungsi tersebut merujuk ke lokasi stack. Perubahan apapun yang dilakukan fungsi tersebut terhadap nilai parameter sebenarnya mengubah nilai stack. Pada saat fungsi tersebut berakhir, compiler C akan melepaskan stack dan demikian juga perubahan-perubahan yang dilakukan fungsi tersebut terhadap lokasi stack tersebut. Lokasi memori yang berisi setiap nilai variabel sebenarnya tidak pernah direfensi oleh fungsi tersebut, jadi dengan memanggil berdasarkan nilai, sebuah fungsi tidak dapat melakukan perngubahan terhadap nilai variabel yang tetap ada setelah fungsi tersebut berakhir.

Secara default compiler C melewatkan parameter-parameter kepada fungsi dengan menggunakan cara pemgaggilan berdasarkan nilai, padahal dengan menggunakan pemanggilan berdasarkan nilai, fungsi-fungsi tidak dapat mengubah nilai dari sebuah parameter yang dilewatkan ke fungsi tersebut, sedangkan pada kebanyakan program fungsi akan perlu mengubah variabel seperti pada fungsi pembacaan informasi dari sebuah file yang membutuhkan sebuah array string karakter untuk menempatkan informasi tadi.

Apabila sebuah fungsi membutuhkan perubahan nilai dari sebuah parameter, maka program tersebut harus melewatkan parameter tersebut ke fungsi dengan menggunakan pemanggilan berdasarkan referensi. Perbedaan antara pemanggilan berdasarkan nilai dengan pemanggilan berdasarkan referensi adalah bahwa dengan menggunakan pemanggilan berdasarkan nilai , fungsi akan menerima salinan dari nilai sebuah parameter, sedangkan dengan pemanggilan berdasarkan refernsi akan menerima alamat memori variabel tersebut. Dengan demikian fungsi tadi dapat merubah nilai yang tersimpan pada suatu lokasi memori tertentu, yang tetap ada meskipun fungsi berakhir. Untuk menggunakan pemanggilan berdasarkan refensi, program harus menggunakan yang disebut pointer. Sebuah pointer untuk sementara anggaplah sebagai suatu alamat memori (pada bahasan selanjutnya pointer akan dipelajari lebih detail). Untuk menugaskan sebuah alamat variabel ke sebuah pointer, maka pada compiler C harus dengan menggunakan operator alamat yaitu &.

Sebuah variabel pada hakekatnya adalah sebuah nama yang ditugaskan ke sebuah lokasi memori atau lebih. Pada saat program dijalankan setiap variabel berdiam di lokasi memorinya sendiri. Program akan mencari lokasi variabel di memori dengan menggunakan alamat memori variabel tersebut. Untuk menentukan alamat sebuah variabel digunakan dengan operator milik C yaitu &, sebagai contoh perhatikan program pendek berikut ini.

#include <stdio.h>

void main(void)

{

int a = 1, b = 2, c = 3;

printf (“The address of a is %x the value of a is %d\n”, &a, a);

printf (“The address of b is %x the value of b is %d\n”, &b, b);

printf (“The address of c is %x the value of c is %d\n”, &c, c);

}

Perhatikan keluaran dari program pendek tersebut setelah anda kompilasi, maka apabila tidak terdapat kesalahan sintaks, maka keluaran yang dihasilkan adalah sebagai berikut :

The address of a is fff4 the value of a is 1

The address of a is fff2 the value of a is 2

The address of a is fff0 the value of a is 3

Apabila program melewatkan sebuah alamat ke sebuah fungsi, maka harus memberitahukan compiler C bahwa fungsi tersebut akan menggunakan sebuah pointer (alamat memori) dari seuatu variabel, bukan sebuah nilai variabel. Untuk melakukan itu harus dideklarasikan sebuah variabel pointer. Pendeklarasian sebuah variabel pointer mirip dengan pendeklarasianvariabel standard, dalam hal ini harus dideklarasikan sebuah nama dan tipe variabel. Perbedannya adalah bahwa nama variabel pointer harus didahului dengan sebuah tanda asteris (*). Pendeklarasian berikut akan membentuk variabel pointer yang menyimpan tipe in, float dan char.

int *i_pointer;

float *f_pointer;

char *c_pointer;

Setelah mendeklarasikan sebuah variabel pointer, dilanjutkan dengan menugaskan ke variabel tersebut, sebuah alamat memori. Pernyataan berikut mencontohkan penugasan alamat dari variabel integer a ke variabel pointer i_pointer .

i_pointer = &a;

lalu untuk menggunakan nilai yang ditunjuk oleh variabel pointer, program harus menggunakan operator redireksi mili compiler C yang berupa tanda asterisk(*). Sebagai contoh pernyataan berikut akan menugaskan nilai 5 ke variabel a yang alamatnya disimpan dalam variabel i_pointer.

*i_pointer = 5;

dengan cara yang sama, pernyataan berikut menugaskan variabel b nilai yang sekarang telah ditunjuk oleh variabel i_pointer.

b = *i_pointer;

apabila diinginkan menggunakan nilai yang ditunjuk oleh sebuah variabel pointer, maka dapat menggunakan operator redireksi (*). Apabila menghendaki untuk menugaskan sebuah alamat variabel ke sebuah variabel pointer dapat menggunakan operator alamat (&). Program pendek berikut ini menggambarkan penggunakaan sebuah variabel pointer. Program tersebut menugaskan variabel pointer i_pointer ke alamat variabel a. Pragram tersebut kemudian mengguankan variabel pointer untuk mengubah, menampilkan dan menugaskan nilai variabel tersebut.

Latihan 5.4

#include <stdio.h>

void main(void)

{

int a = 1, b = 2;

int *i_pointer;

//Assign an address

i_pointer = &a;

// change the value pointed to by i_pointer to 5

*i_pointer = 5;

//Display the value

printf (“Value pointed to by i_ponter is %d the variable a is %d\n”, *i_pointer, a);

//Assign the value

b = *i_pointer;

printf(“Value of b is %d\n”, b);

printf (“Value of i_pointer %x\n”, i_pointer);

}

Cara-cara diatas digunakan untuk menuntun dalam mempelajari proses perubahan nilai sebuah parameter di dalam sebuah fungsi dengan menggunakan pemanggilan berdasarkan referensi, untuk melewatkan alamat dari variabel tersebut. Di dalam suatu fungsi harus menggunakan pointer seperti latihan berikut ini.

Latihan 5.5

#include <stdio.h>

void display_and_change (int *first, int *second, int *third)

{

printf(“Original function values %d %d %d\n”, *first, *second, *third);

*first += 100;

*second += 100;

*third += 100;

printf (“Ending function values %d %d %d\n”, *first, *second, *third);

}

void main(void)

{

int a = 1, b = 2, c = 3;

display_and_change (&a, &b, &c);

printf (“Ending values in main %d %d %d\n”, a, b, c);

}

  1. Variabel Static

Pada bahasa pemrograman C variabel-variabel yang dideklarasikan di dalam sebuah fungsi seringkali disebut sebagai otomatis karena compiler C secara otomatis akan menciptakannya pada saat fungsi tersebut dimulai dan menghapuskannya setelah fungsi tersebut berakhit. Masa hidup variabel otomatis terjadi karena compiler menyimpan variabel fungsi tersebut secara sementara dalam stack. Akibatnya apabila sebuah fungsi menugaskan sebuah nilai ke sebuah variabel saat ia diaktifkan, nilai variabel tadi akan hilang saat fungsi tersebut berakhir. Lalu apabila dipanggil kembali fungsi tersebut pada waktu berikutnya, nilaivariabel tadi masih belum didefinisikan. tergantung kepada pemrosesan yang dilakukan oleh fungsi, adakalanya dikehendaki variabel fungsi untuk mengingat nilai terakhir yang ditugaskan kepadanya. Sebagai contoh anggaplah bahwa telah ditulis sebuah fungsi dengan nama print_reportcard yang akan mencetak kartu laporan setiap siswa pada suatu sekolah. Fungsi mungkin menggunakan variabel student_id untuk menampungnomor identifikasi siswa terakhir yang kartu laporannya telah tercetak. Dengan cara ini fungsi ini, tanpa harus diberitahukan lagi, dapat memulai menampilkan milik siswa yang berikutnya. Agar variabel local pada fungsi masih mengingat nilai terakhirnya maka harus dideklarasikan variabel tersebut dengan kata kunci static seperti ayng diperlihatkan dalam contoh berikut ini.

void print_reportcard (int pronter_number)

{

statis int student_id

//Pernyataan-pernyataan lainnya

}

Untruk lebih memahami variabel static ini cobalah latihan berikut ini yang menggambarkan penggunaan sebuah variabel static di dalam sebuah fungsi. Program ini, yang menggunakan fungsi print_repordcard yang diawali dengan menugaskan nilai 100 ke variabel student_id, kemudian setiap kali program tersebut memanggil fungsi tersebut, fungsi tersebut menampilkan nilainya dengan 1.

Latihan 5.6

#include <stdio.h>

void print_reportcard(int printer_number)

{

static int student_id = 100;

printf(“Printing report card for student %d\n”, student_id);

student_id++;

// Other statement here

}

void main(void)

{

print_reportcard(1);

print_reportcard(1);

print_reportcard(1);

}

Apabila program tersebut dikompilasi dan dieksekusi serta tidak ada kesalahan sintaks, maka pada layar akan menampilkan sebagai berikut :

Printing report card for student 100

Printing report card for student 101

Printing report card for student 102

Seperti yang terlihat bahwa variabel student_id tetap menyimpan nilainya dari satu pengaktifan fungsi ke pengaktifan berikutnya..

Pada saat fungsi mendeklarasikan sebuah variabel statis, compiler C memungkinkan proses inisialisasi variabel yang dideklarasikan tersebut, seperti dalam contoh berikut ini.

void print_reportcard(int printer_number)

{

static int student_id = 100; //Diinisialisasi sekali

// Pernyataan-pernyataan

}

Pada saatdideklarasikan sebuah variabel sebagai static, compiler C akan menginisialisasi variabel tersebutke nilai yang telah ditentukan. Apabila fungsi ini diaktifkan nantinya penugasan ini tidak dijalankan. Inisialisasi variabel fungsi ini berbeda dengan pemrosesan yang biasanya dilakukan C di dalam fungsi. Pada kasus fungsi berikut C akan menginisialisasi variabel count setiap kali fungsi ini dipanggil.

void some _function (int age, char *name)

{

int count =1; // Diinisialisasi setiap pemanggilan

// Pernyataan-pernyataan

}

  1. Rekursi

Seperti yang telah dipalajari pada bab-bab sebelumnya, Pemrograman C memungkinkan untuk memecah-mecah program dalam potongan-potongan program lebih kecil yang disebut dengan fungsi. Dengan menggunakan fungsi, program menjadi lebih mudah untuk dimengerti, di

program dan diuji. Sebagai tambahan fungsi yang dibuat untuk sebuah program seringkali dapat digunakan oleh program yang lain. Pada saat program dieksekusi, sebuah fungsi bisa saja memanggil fungsi yang lain, yang memanggil fungsi yang lain lagi yang pada gilirannya memanggil beberapa fungsi lainnya lagi untuk melakukan sesuatu. Pada kasus tertentu program C malah memungkinkan sebuah fungsi untuk memanggil dirinya sendiri, fungsi yang demikian disebut dengan fungsi rekursif yang memanggil dirinya sendiri untuk melakukan sesuatu operasi tertentu.Proses dari sebuah fungsi yang memanggil dirinya sendiri disebut sebagai rekursi. Contoh yang sering ditunjukkan untuk menggambarkan pada fungsi rekursif ini adalah penggunaan masalah factorial dimana nilai factorial dari 1 adalah 1, nilai factorial 2 adalah 2*1, nilai factorial dari 3 adalah 3*2*1 demikian juga seterusnya untuk nilai factorial 4 adalah 4*3*2*1. Proses semacam ini dapat terus sampai tak terhingga, apabila diperhatikan proses penentuan nilai factorial sebenarnya factorial dari 4 adalah 4 * factorial 3, demikan juga nilai factorial dari 3 sebenarnya adalah 3* nilai factorial 2, demikian seterusnya, sehingga apabila dibuat funsi rekursi factorial dengan menggunakan batasan nilai factorial 1 sampai dengan 5 adalah sebagai berikut..

Latihan 5.7

#include <stdio.h>

int factorial (int value)

{

if (value == 1)

return(1)

else

return (value * factorial(value-1));

}

void main(void)

{

int i;

for (1 = 1; 1<= 5; i++)

printf (“The factorial of %d is %d\n”, i, factorial(i));

}

Fungsi factorial menerima suatu nilai parameter tertentu. Pada saat fungsi tersebut dimulai, pertama-tama ia akan memeriksa nilai berupa 1 atau tidak, yang berdasarkan definsi factorial, adalah 1. Bilai nilainya 1, fungsi tersebutmengembalikan nilai 1, bilai nilainya bukan 1, fungsi tersebut mengembalikan hasil dari nilai tersebut dikalikan dengan faktorial dari nilai tersebut dikurangi 1. Anggaplah, sebagai contoh fungsi ini diaktifkan dengan nilai 3. Fungsi tersebut akan mengembalikan nilai 3 * factorial(3-1). Pada saat compiler C menemukan adanya pemanggilan sebuah fungsi di dalam pernyataan return, compiler akan mengaktikan fungsi tersebut untuk yang kedua kalinya, hanya kali ini dengan nilai 3-1 atau 2. Sekali lagi, karena nilainya bukan 1, fungsi tersebut akan mengembalikan nilai 2 * factorial(2-1). Pada pengaktifan fungsi tersebut , nilai sekarang adalah 1. Sebagai hasilnya, fungsi tadi mengembalikan nilai 1 ke fungsi yang memanggilnya, yang pada gilirannya lagi mengembalikan hasil dari 2 * 1 kepada fungsi yang memanggilnya, yang mengembalikan hasil dari 3 * 2 * 1 ke pemanggilnya.

Leave a comment

No comments yet.

Comments RSS TrackBack Identifier URI

Leave a comment