Minggu, 13 April 2014

Recursion

Sebuah fungsi rekursif adalah fungsi yang memanggil dirinya sendiri baik secara langsung maupun tidak langsung. Jika fungsi rekursif disebut dengan base case, fungsi hanya mengembalikan hasilnya. Jika fungsi disebut dengan masalah yang lebih kompleks, fungsi membagi masalah ke dalam dua konseptual potongan : sepotong  fungsi tahu bagaimana melakukannya dan versi yang sedikit lebih kecil dari  masalah aslinya. Karena masalah baru ini tampak seperti masalah asli , fungsi rekursif membuat sebuah panggilan untuk bekerja pada masalah yang lebih kecil .


Untuk rekursi untuk mengakhiri , setiap kali fungsi rekursif menyebut dirinya dengan versi yang sedikit lebih sederhana dari masalah asli , urutan masalah yang lebih kecil dan lebih kecil harus berkumpul di base case. Bila fungsi mengakui kasus dasar , hasilnya dikembalikan ke fungsi panggilan sebelumnya, dan urutan pengembalian terjadi sampai panggilan asli dari Fungsi akhirnya kembali ke hasil akhir .


Standar C tidak menentukan urutan di mana operan dari sebagian besar operator ( including + ) untuk dievaluasi . Dari sekian banyak operator C , standar menentukan urutan evaluasi operan hanya operator && , | | , koma ( , ) operator dan : ? . Pertama dari ini
operator biner yang dua operan dievaluasi dari kiri ke kanan . Operator  terakhir hanya ternary C operator. Operator paling kiri dievaluasi pertama; jika operator paling kiri bernilai nol ,operator tengah dievaluasi berikutnya dan operator terakhir diabaikan ; jika mengevaluasi operator paling kiri ke nol , operator ketiga dievaluasi berikutnya dan operator tengah diabaikan.


Contoh:
/* Fig. 5.14: fig05_14.c
 Recursive factorial function */
 #include <stdio.h>

long factorial( long number ); /* function prototype */

/* function main begins program execution */
int main( void )
 {
 int i; /* counter */

 /* loop 11 times; during each iteration, calculate
 factorial( i ) and display result */
 for ( i = 0; i <= 10; i++ ) {
 printf( "%2d! = %ld\n", i, factorial( i ));
 } /* end for */

 return 0; /* indicates successful termination */
 } /* end main */

/* recursive definition of function factorial */
long factorial( long number )
{
/* base case */
if ( number <= 1 ) {
return 1;
} /* end if */
else { /* recursive step */
return ( number * factorial( number - 1 ) );
} /* end else */

} /* end function factorial */

Sabtu, 12 April 2014

Calling Functions By Value and By Reference

Ada 2 cara yang bisa kita gunakan untuk memanggil sebuah fungsi di beberapa bahasa pemrograman, yaitu call by value dan call by references


Call by Value
Yang dimaksud dengan call by value adalah metode yang menyalin data (nilai) dari argumen yang memanggil function ke parameter dari function tersebut. Akibatnya jika ada perubahan nilai pada parameter function tidak akan berpengaruh pada nilai aslinya (nilai yang ada pada argumen program yang memanggil function tersebut). Sebaliknya untuk call by reference yang disalin bulan nilainya tetapi alamat memori yang menyimpan nilai tersebut sehingga jika terjadi perubahan-perubahan nilai pada parameter function, maka secara otomatis nilai argumennya juga akan ikut berubah.
Contoh :

#include <stdio.h>
#include <conio.h>

int kali(int a,int b, int c) //parameter formal
{
int x;
x = a * b * c;
return(x);
}


int main()
{
int a,b,c;
printf(”Masukkan angka 1 : “);
scanf(”%d”,&a);
printf(”Masukkan angka 2 : “);
scanf(”%d”,&b);
printf(”Masukkan angka 3 : “);
scanf(”%d”,&c);

printf(”Hasil perkalian ketiga bilangan adalah %d”,kali(a,b,c)); //parameter aktual
getch();
return(0);

}

Call by References
Pelewatan parameter ke dalam fungsi dengan menyalin alamat dari suatu variabel aktualnya. Fungsi yang menerima kiriman alamat ini akan menggunakan alamat yang sama untuk mendapatkan nilai datanya. Hal ini dilakukan dengan menggunakan pointer. Pointer adalah variabel yang merujuk pada alamat lokasi suatu memori tertentu, variable pointer dapat dideklarasikan dengan menuliskan nama variabelnya diawali dengan asterisk (‘*’). Perubahan yang terjadi pada variabel asal akan mengakibatkan perubahan pada variabel pointernya dan sebaliknya.

Contoh: 
#include <stdio.h>
#include <conio.h>

void desc_sort(int *bil1,int *bil2) //parameter formal
{

if(*bil1<*bil2)
{
*bil1 = *bil1 + *bil2;
*bil2 = *bil1 - *bil2;
*bil1 = *bil1 - *bil2;
}

}

int main() {
int a,b,c;

printf(”Masukkan angka 1 : “);
scanf(”%d”,&a);
printf(”Masukkan angka 2 : “);
scanf(”%d”,&b);
printf(”Masukkan angka 3 : “);
scanf(”%d”,&c);

desc_sort(&a,&b); //parameter aktual
desc_sort(&a,&c); //parameter aktual
desc_sort(&b,&c); //parameter aktual
printf(”Hasil descending sort adalah %2d %2d %2d”,a,b,c);

getch();
return(0);

}


Headers

Sebuah file header adalah file dengan ekstensi .h yang berisi deklarasi fungsi C dan definisi makro dan untuk dibagi antara beberapa file sumber extension.. Ada dua jenis file header: file yang menulis programmer dan file yang datang dengan kompiler Anda.  Anda meminta penggunaan file header dalam program Anda dengan memasukkan, dengan C preprocessing direktif #include seperti Anda telah melihat masuknya file header stdio.h, yang datang bersama dengan kompiler Anda. 

Termasuk file header sama dengan menyalin isi dari file header tapi kami tidak melakukannya karena akan sangat rawan kesalahan dan itu bukan ide yang baik untuk menyalin isi dari file header di file sumber, khususnya jika kita punya file beberapa sumber yang terdiri dari program kami.

Dibawah ini adalah macam-macam header yang bisa kita gunakan di program C:

Storage Classes

Didalam Identifier program mempunyai attributes storages class, storage duration, scope dan linkage. Didalam C menyediakan 4 kelas penyimpanan, 4 penyimpanan tersebut itu : auto, register, extern, dan static. Dan hanya satu storage class yang digunakan untuk deklarasi tertentu. Penyimpnan didalam identifier adalah identifier yang ada didalam memory.

  • Kelas penyimpanan auto adalah kelas penyimpanan default untuk semua variabel lokal.

Contoh :
{
   int mount;
   auto int month;
}

Contoh di atas mendefinisikan dua variabel dengan kelas penyimpanan yang sama, auto hanya dapat digunakan dalam fungsi, yaitu, variabel lokal.

  • Kelas penyimpanan register digunakan untuk mendefinisikan variabel lokal yang harus disimpan dalam register bukan RAM. Ini berarti bahwa variabel memiliki ukuran maksimum sama dengan ukuran register (biasanya satu kata) dan tidak dapat memiliki unary '&' operator diterapkan untuk itu (karena tidak memiliki lokasi memori).

Contoh:
{
   register int  miles;
}

Register seharusnya hanya digunakan untuk variabel yang membutuhkan akses cepat seperti counter. Hal ini juga harus dicatat bahwa mendefinisikan 'mendaftarkan' tidak berarti bahwa variabel akan disimpan di register. Ini berarti bahwa hal itu MUNGKIN disimpan di register tergantung pada hardware dan pembatasan pelaksanaan.

  • Kelas penyimpanan statis memerintahkan compiler untuk menyimpan variabel lokal yang ada selama hidup-waktu program ini bukannya menciptakan dan menghancurkan setiap kali datang ke dalam dan keluar dari ruang lingkup. Oleh karena itu, membuat variabel lokal statis memungkinkan mereka untuk mempertahankan nilai-nilai mereka antara panggilan fungsi. Pengubah statis juga dapat diterapkan ke variabel global. Bila ini dilakukan, hal itu menyebabkan bahwa ruang lingkup variabel harus dibatasi ke file di mana ia dideklarasikan. Dalam C + +, ketika statis digunakan pada anggota data kelas, hal itu menyebabkan hanya satu salinan yang anggota untuk digunakan bersama oleh semua objek kelasnya.


  • Kelas penyimpanan extern digunakan untuk memberikan referensi dari variabel global yang terlihat untuk semua file program. Bila Anda menggunakan 'extern' variabel tidak dapat diinisialisasi sebagai semua hal ini adalah titik nama variabel di lokasi penyimpanan yang telah ditetapkan sebelumnya.  Bila Anda memiliki beberapa file dan Anda mendefinisikan variabel global atau fungsi yang akan digunakan dalam file lain juga, maka extern akan digunakan dalam file lain untuk memberikan referensi variabel atau fungsi yang didefinisikan. Hanya untuk pemahaman extern digunakan untuk mendeklarasikan variabel global atau fungsi dalam file lain.



Example: a Game of Chance

Salah satu game terpopuler “game of chance” adalah sebuah permainan dadu yang juga dikenal sebagai “craps”, yang biasanya dimainkan di kasino diseluruh dunia. Peraturan permainan tersebut adalah:
A player rolls two dice. Each die has six faces. These faces contain 1, 2, 3, 4, 5, and 6
spots. After the dice have come to rest, the sum of the spots on the two upward faces is
calculated. If the sum is 7 or 11 on the first throw, the player wins. If the sum is 2, 3,
or 12 on the first throw (called “craps”), the player loses (i.e., the “house” wins). If the
sum is 4, 5, 6, 8, 9, or 10 on the first throw, then that sum becomes the player’s
“point.” To win, you must continue rolling the dice until you “make your point.” The
player loses by rolling a 7 before making the point.
Contoh program:

/* Fig. 5.10: fig05_10.c Craps */
#include <stdio.h>
#include <stdlib.h>
#include <time.h> /* contains prototype for function time */
enum Status { CONTINUE, WON, LOST };
int rollDice( void ); /* function prototype */
/* function main begins program execution */
 int main( void )
 {
int sum; /* sum of rolled dice */
 int myPoint; /* point earned */

enum Status gameStatus;

srand( time( NULL ) );
sum = rollDice(); /* first roll of the dice */

/* determine game status based on sum of dice */
 switch( sum ) {

 /* win on first roll */
 case 7:
 case 11:
 gameStatus = WON;
 break;

 /* lose on first roll */
 case 2:
 case 3:
 case 12:
 gameStatus = LOST;
 break;

 /* remember point */
 default:
 gameStatus = CONTINUE;
 myPoint = sum;
 printf( "Point is %d\n", myPoint );
 break; /* optional */
 } /* end switch */
/* while game not complete */
 while ( gameStatus == CONTINUE ) {
sum = rollDice(); /* roll dice again */
/* determine game status */
 if ( sum == myPoint ) { /* win by making point */
 gameStatus = WON; /* game over, player won */
 } /* end if */
 else {
 if ( sum == 7 ) { /* lose by rolling 7 */
 gameStatus = LOST; /* game over, player lost */
 } /* end if */
 } /* end else */
 } /* end while */

 /* display won or lost message */
 if ( gameStatus == WON ) { /* did player win? */
 printf( "Player wins\n" );
 } /* end if */
else { /* player lost */
 printf( "Player loses\n" );
 } /* end else */

 return 0; /* indicates successful termination */
 } /* end main */

 /* roll dice, calculate sum and display results */
 int rollDice( void )
 {
 int die1; /* first die */
 int die2; /* second die */
 int workSum; /* sum of dice */

 die1 = 1 + ( rand() % 6 ); /* pick random die1 value */
 die2 = 1 + ( rand() % 6 ); /* pick random die2 value */
 workSum = die1 + die2; /* sum die1 and die2 */

 /* display results of this roll */
 printf( "Player rolled %d + %d = %d\n", die1, die2, workSum );
 return workSum; /* return sum of dice */

 } /* end function rollRice */


Function Prorotypes

Sebuah  fungsi prototypes mendeklarasikan tipe return dari  fungsi dan menyatakan angka, tipe, dan urutan parameter fungsi  untuk menerima .
Fungsi prototype memungkinkan compiler untuk memverifikasi bahwa fungsi disebut dengan benar
Compiler mengabaikan nama-nama variabel yang disebutkan dalam prototipe fungsi bukan melalui kedua variable tersebut.

Tabel Promotion hierarchy dari tipe data.

Data type
Printf conversion specification
Scanf conversion specification
Long double
%Lf
%Lf
double
%f
%lf
float
%f
%f
Unsigned long int
%lu
%lu
Long int
%ld
%ld
Unisigned int
%u
%u
int
%d
%d
Unisigned short
%hu
%hu
short
%hd
%hd
char
%c
%c

Random Number Generation

Function Raid akan menghasilkan nilai interger antara 0 dan Rand_max yang akan didefinisikan didalam c yang bernilai 32.767. Nilai yang dihasilkan oleh Rand sendiri akan ditingkatkan dan bergeser dengan tujuan menghasilkan nilai yang berkisar tertentu.  Prototipe sendiri mempunyai tugas dalam rand dan srand yang ada di dalam <stdlib.h>.
Fungsi Srand di C digunakan untuk mengacak sebuah program tertentu. Srand biasanya dimasukan didalam program setelah dilakukanya debugged. Debugging berfungsi untuk menghilangkan Srand, hal ini digunakan untuk memastikan penggulangan, yang paling penting untu memastikan koreksi ke program generasi nomor acak bekerja dengan baik.
Dalam pengacakan tidak perlu memasukan seed, tetapi menggunakan srand. Rumus dalam pengeseran nomor acak adalah : n = a + rand ( ) % b .

Contoh Program: Rolling a Six-Sided Die 6000 Times
/* Fig. 5.8: fig05_08.c
 Roll a six-sided die 6000 times */
 #include <stdio.h>
 #include <stdlib.h>

 /* function main begins program execution */
 int main( void )
 {
 int frequency1 = 0; /* rolled 1 counter */
 int frequency2 = 0; /* rolled 2 counter */
 int frequency3 = 0; /* rolled 3 counter */
 int frequency4 = 0; /* rolled 4 counter */
 int frequency5 = 0; /* rolled 5 counter */
 int frequency6 = 0; /* rolled 6 counter */

 int roll; /* roll counter, value 1 to 6000 */
 int face; /* represents one roll of the die, value 1 to 6 */

 /* loop 6000 times and summarize results */
 for ( roll = 1; roll <= 6000; roll++ ) {
 face = 1 + rand() % 6; /* random number from 1 to 6 */

 /* determine face value and increment appropriate counter */
 switch ( face ) {

 case 1: /* rolled 1 */
 ++frequency1;
 break;

 case 2: /* rolled 2 */
 ++frequency2;
 break;

 case 3: /* rolled 3 */
 ++frequency3;
 break;

 case 4: /* rolled 4 */
 ++frequency4;
 break;

 case 5: /* rolled 5 */
 ++frequency5;
 break;

 case 6: /* rolled 6 */
 ++frequency6;
 break; /* optional */
 } /* end switch */
 } /* end for */

 /* display results in tabular format */
 printf( " \n", "Face", "Frequency" );
 printf( " 1%13d\n", frequency1 );
 printf( " 2%13d\n", frequency2 );
 printf( " 3%13d\n", frequency3 );
 printf( " 4%13d\n", frequency4 );
 printf( " 5%13d\n", frequency5 );
 printf( " 6%13d\n", frequency6 );
 return 0; /* indicates successful termination */
 } /* end main */


Output: 

Function Call Stack and Activation Records

Untuk mengerti bagaimana C melakukan pemanggilan fungsi, pertama kita harus memahami tentang data struktur yang dikenal sebagai stack. Kita bisa membayangkan stack seperti sebuah tumpukan piring, ketika kita meletakan sebuah piring di tumpukan maka kita akan meletakannya di atas tumpukan, sama seperti ketika kita ingin memindahkan piring dari tumpukan itu, kita harus memindahkannya mulai dari atas. Stack juga disebut LIFO (Last In First Out), item yang pertama masuk adalah item yang pertama keluar.

Ketika program memanggil fungsi, fungsi yang dipanggil harus tau bagaimana cara kembali ke pemanggil, jadi alamat pengembalian di dorong ke program yang di eksekusi. Jika serangkaian fungsi dipanggil, alamat dari sebuah fungsi akan kembali di dorong ke prinsip  “last in first out” jadi setiap fungsi dapat dipanggil ke pemanggil.

Ketika sebuah fungsi kembali ke pemanggil, catatan aktivasi dan variable lokal tidak dikenal pada program. Pastinya jumlah memory pada komputer terbatas, sehingga hanya sebagian memory saja yang dapat digunakan untuk menyimpan catatan aktivasi.

Function

Sebuah variabel lokal hanya dikenal dalam definisi fungsi . Fungsi lain tidak diperbolehkan untuk tahu nama-nama variabel lokal fungsi , dan tidak pula fungsi apapun diperbolehkan untuk mengetahui pelaksanaan rincian fungsi lainnya .


Function Definition


Contoh:
 /* Fig. 5.3: fig05_03.c
  Creating and using a programmer-defined function */
#include <stdio.h>

int square( int y );

/* function prototype *//* function main begins program execution */
int main( void )
{
    int x; /* counter */

    /* loop 10 times and calculate and output square of x each time */
    for ( x = 1; x <= 10; x++ ) {
       printf( "%d ", square (x)); /* function call */
    } /* end for */

    printf( "\n" );
    return 0; /* indicates successful termination */
} /* end main */

/* square function definition returns square of parameter */
int square( int y ) /* y is a copy of argument to function */
{
    return y * y; /* returns square of y as an int */
} /* end function square */



Screenshots:

Function Maximum



Contoh:
Pada contoh ini programer mendefinisikan fungsi maximumuntuk determine dan return dari tiga integers,yang ketiganya diinputkan lewat perintah scanf,selanjutnya lewat maximum,yang mana determine integer terbesar.Nilai dikembalikan  ke main oleh stetment return dalam stetment maximum .Nilai yang dikembalikan di tampilkan oleh statment perintah  printf.

/* Fig. 5.4: fig05_04.c
  Finding the maximum of three integers */
#include <stdio.h>

int maximum( int x, int y, int z ); /* function prototype */

/* function main begins program execution */
 int main( void )
 {
 int number1; /* first integer */
 int number2; /* second integer */
 int number3; /* third integer */

 printf( "Enter three integers: " );
 scanf( "%d%d%d", &number1, &number2, &number3 );

 /* number1, number2 and number3 are arguments
     to the maximum function call */
 printf( "Maximum is: %d\n",maximum(number1,number2,number3) );
 return 0; /* indicates successful termination */
 } /* end main */

/* Function maximum definition */
/* x, y and z are parameters */
int maximum( int x, int y, int z )
{
   int max = x; /* assume x is largest */

   if ( y > max ) { /* if y is larger than max, assign y to max */
     max = y;
   } /* end if */

   if ( z > max ) { /* if z is larger than max, assign z to max */
     max = z;
} /* end if */

return max; /* max is largest value */
} /* end function maximum */

Screenshots:


Format umum untuk definisi fungsi adalah :
return-value-type function-name( parameter-list)
{
definitions
statement
}

Tipe stetment  return-value-type  merupakan jenis nilai kembali ke fungsi panggilan. Jika fungsi tidak mengembalikan nilai , return - value -type dinyatakan sebagai declared seperti void .function-name adalah  valid identifier . Parameter -list adalahsebuah comma-separate  yang berisi definisi dari variabel-variabel yang akan dilewatkan ke fungsi . Jika fungsi tidak menerima nilai-nilai , parameter-list dinyatakan sebagai declared seperti void . Function -body adalah himpunan definisi dan pernyataan yang merupakan fungsi .

• Argumen yang dilewatkan ke fungsi harus sesuai dalam angka, tipe dan keteraturan dengan parameter dalam definisi fungsi .
• Ketika program bertemu dengan pemanggilan fungsi , kontrol ditransfer dari point  of infunction
untuk memanggil fungsi , stetment itu disebut fungsi yang dieksekusi dan kontrol kembali ke
pemanggil .
• Sebuah fungsi dapat mengembalikan kontrol ke pemanggil dalam satu dari tiga cara . Jika fungsi tidak mengembalikan nilai , kontrol dikembalikan ketika function-ending right brace tercapai , atau dengan menjalankan pernyataan
     return;

Math Library Function

Fungsi math library memungkinkan kita untuk melakukan perhitungan matematis umum tertentu. Fungsi biasanya digunakan dalam sebuah program dengan cara menuliskan nama fungsi yang kemudian diikuti dengan kurung pembuka dan diikuti oleh argument dan kemudian diberi kurung penutup. Sebagai contoh, seorang programmer menginginkan untuk menghitung dan mencetak akar kuadrat dari 900, maka yang ditulis :

-          printf( "%.2f", sqrt( 900.0) );

Ketika pernyataan ini dijalankan, fungsi math library sqrt dipanggil untuk menghitung akar kuadrat dari jumlah yang terkandung dalam tanda kurung ( 900.0). Nomor 900.0 adalah argumen dari fungsi sqrt . Fungsi di math library ini adalah menjadikan nilai floating poin dengan menggunakan %f. 


Beberapa fungsi C math library diringkas dalam gambar dibawah ini. Dalam gambar , variabelx dan y adalah bertipe data double : 


Program Modules in C

Sebuah contoh analogi umum untuk menjelaskan bagaimana program dalam C berjalan adalah bentuk hirarki manajemen. Fungsi kepala (fungsi pemanggil) meminta pekerja (yang disebut fungsi) untuk melakukan tugas dan melaporkan kembali ketika tugas telah dilakukan. Fungsi kepala tidak tahu bagaimana fungsi pekerja melakukan tugas-tugas yang diperintahkan. Sehingga pekerja dapat membuat fungsi-fungsi pekerja lainnya seperti pada gambar, sehingga pekerja 1 bertindak sebagai fungsi bos untuk pekerja 4 dan pekerja 5.