Senin, 12 Mei 2014

Case Study: Card Shuffling and Dealing Simulation

Kali ini kita akan membahas tentang perancangan program pengacakan kartu dan membuat program simulasinya. Program ini nantinya akan bisa digunakan untuk di implementasikan untuk program permainan kartu tertentu. Menggunakan metode top-down, pendekatan bertahap, kita akan mengembangkan sebuah program untuk mengocok 52 kartu dan bergilir masing-masing kartu. 

Sekumpulan kartu akan di acak sebagai berikut. Pertama, deck array dibiarkan kosong. Lalu baris (0-3) dan kolom(1-12) akan dibiarkan kosong.Kartu nomor 1 di masukan ke elemen array[baris][kolom] untuk mengindikasikan kartu ini adalah kartu pertama yang dibagikan ke dalam deck. Proses ini akan berlanjut di kartu nomor 2,3 sampai kartu ke 52. Saat deck array di isi dengan nomor kartu, itu memungkinkan untuk memilih sebuah kartu 2 kali. Deck[baris][kolom] tidak akan kosong ketika dipilih, pemilihan nomor kartu yang sama akan di abaikan sampai kartu yang belum terpilih dipilih, proses ini akan berlanjut hingga deck array terpenuhi.


Hubungan antara Pointer dan Array

Array dan pointer berhubungan dalam C dan dapat digunakan secara bergantian. Array dapat dianggap sebagai pointer konstan. Pointer dapat digunakan untuk melakukan operasi yang melibatkan array subscripting.
Seandainya integer array b[5] dan bPtr adalah variabel integer pointer yang telah didefinisikan. Kita dapat mengatur bPtr sama dengan alamat elemen pertama dalam array b dengan pernyataan (bPtr = b;). Pernyataan ini setara dengan elemen array dengan pernyataan (bPtr = &b[ 0 ];)
Elemen array b[3] dapat dirujuk dengan ekspresi pointer *( bPtr + 3 ).  Angka 3 adalah offset untuk pointer. Saat pointer menunjuk ke awal array, offset berfungsi menunjukkan elemen array yang harus dirujuk dan nilai offset identik dengan subskrip array. Notasi sebelumnya disebut sebagai penunjuk offset notasi. Kurung diperlukan karena * lebih didahulukan dari +. Tanpa tanda kurung, ekspresi * bPtr akan dijalankan terlebih dahulu baru melakukan penambahan.
Array itu sendiri dapat diperlakukan sebagai pointer dan digunakan di aritmatika pointer. Secara umum, semua ekspresi subscripted array dapat ditulis dengan pointer dan offset. Dalam kasus ini, pointer offset digunakan dengan nama array sebagai pointer.

Ingat bahwa nama array dasarnya pointer konstan sehingga selalu mengarah ke awal array. Dengan demikian, ekspresi b += 3 tidak valid karena ia berusaha untuk mengubah nilai nama array dengan pointer aritmatika.

            Untuk lebih lanjut menggambarkan kemampuan array dan pointer, mari kita lihat dalam program. 

Fungsi copy1 adalah  untuk menyalin string di dalam s2 ke karakter array s1. Fungsi variabel counter i adalah sebagai array subskrip. Header menunjukkan bahwa i diinisialisasi ke nol dan bertambah satu setiap kali dari loop. Ekspresi s1 [i] = [i] menyalin satu karakter dari s2 ke s1. Loop berakhir karena nilai integer karakter null adalah nol (palsu).
Fungsi copy2 menggunakan pointer dan pointer aritmatika untuk mengcopy string di s2 ke karakter array s1. Header tidak termasuk inisialisasi variabel. Seperti dalam fungsi copy1, ekspresi (* s1 = * s2) melakukan operasi copy. Setelah itu pointer bertambah untuk menunjuk ke elemen seterusnya yaitu array s1 dan karakter berikutnya string s2.
Argumen pertama untuk copy1 dan copy2 harus menjadi sebuah array yang cukup besar untuk menampung string dalam argumen kedua. Jika tidak, kesalahan dapat terjadi ketika digunakan untuk menulis ke lokasi memori yang bukan merupakan bagian dari array. Kedua fungsi parameter masing masing dinyatakan sebagai const char *. Dalam kedua fungsi, argumen kedua disalin ke argumen pertama. Oleh karena itu, parameter kedua dinyatakan untuk menunjuk ke nilai konstan. 

Pointer Expressions dan Pointer Arithmetic

Pointer adalah Operand valid di dalam aritmatika ekspresi, tugas ekspresi dan perbandingan ekspresi. Namun, tidak semua operator yang biasanya digunakan dalam ungkapan-ungkapan ini yang berlaku dalam kaitannya dengan pointer variabel.
Pointer mungkin incremented (++) atau decremented (-), yang berarti integer dapat ditambahkan ke pointer (+ atau + =), integer dapat dikurangi dari pointer (- atau-=) dan satu pointer dapat dikurangi dari yang lain.
Sebagai contoh, seandainya telah ditetapkan array int v[5] dan elemen pertama di lokasi dalam memori adalah 3000 maka pointer vPtr menganggap telah diinisialisasi untuk menunjuk ke v[0], sehingga nilai vPtr adalah 3000. Variabel vPtr dapat diinisialisasi untuk menunjuk ke array v dengan salah satu pernyataan.
vPtr = v;
vPtr = &v[ 0 ];
Di konvensional aritmatika, 3000 + 2 menghasilkan nilai 3002. Hal ini biasanya tidak terjadi dengan pointer aritmatika. Ketika integer ditambahkan atau dikurangkan dari pointer, pointer bukanlah incremented atau decremented. Misalnya, pernyataan vPtr += 2; akan menghasilkan 3008 (3000 + 2 * 4), dengan asumsi bilangan bulat disimpan dalam 4 byte dari memori. Dalam array v, vPtr sekarang akan menunjukkan v[2]. Jika bilangan bulat disimpan dalam byte 2 memori, kemudian perhitungan sebelumnya akan mengakibatkan lokasi memori 3004 (3000 + 2 * 2). Jika array tipe data yang berbeda, pernyataan sebelumnya akan kenaikan pointer oleh dua kali jumlah byte yang dibutuhkan untuk menyimpan objek dari jenis data. Ketika melakukan aritmatika pointer pada karakter array, hasilnya akan konsisten dengan aritmatika biasa.
Jika vPtr telah bertambah dengan 3016 yang menunjuk ke v [4], pernyataan  vPtr -= 4; akan mengatur vPtr kembali ke 3000-awal array. Jika sebuah pointer menjadi incremented atau decremented oleh salah satu, kenaikan (++) dan penurunan (-) maka operator dapat digunakan. Pernyataan
++vPtr;
vPtr++;
akan menambahkan pointer ke lokasi berikutnya dalam array. Lain halnya dengan salah satu pernyataan
--vPtr;
vPtr--;
yaitu akan mengurangkan pointer ke unsur sebelumnya dalam array.
Pointer dapat ditugaskan ke pointer lain jika keduanya memiliki tipe yang sama. Pengecualian aturan ini adalah untuk pointer void, yang merupakan pointer generik yang dapat mewakili jenis pointer. Semua jenis pointer dapat diberikan ke pointer void, dan pointer void dapat memberikan kepada pointer dari jenis apa pun.

Pointer dapat dibandingkan dengan menggunakan kesetaraan dan relasional operator, tetapi perbandingan ada artinya kecuali pointer menunjuk ke elemen array yang sama. Penggunaan perbandingan pointer adalah untuk menentukan apakah pointer adalah NULL.

sizeof Operator

C menyediakan unary operator sizeof untuk menentukan ukuran dalam bit sebuah data array (atau tipe data lainnya) ketika program dijalankan. Ketika di aplikasikan ke nama dari sebuah array seperti pada fig 7.16, operator sizeof mengembalikan jumlah byte ke dalam array sebagai integer. Variabel dengan tipe data float biasanya disimpan di memori 4 byte dan array di definisikan mempunyai 20 elemen.

/* Fig. 7.16: fig07_16.c
Applying sizeof to an array name returns
the number of bytes in the array. */
#include <stdio.h>
size_t getSize(float *ptr); /* prototype */
int main( void )
{
   float array[ 20 ]; /* create array */
   printf( "The number of bytes in the array is %d"
   "\nThe number of bytes returned by getSize is %d\n",
   sizeof( array ), getSize( array ) );
   return 0; /* indicates successful termination */
} /* end main */

/* return size of ptr */
size_t getSize(float *ptr)
{
   return sizeof( ptr );
} /* end function getSize */

Output:  

Jumlah dari elemen array juga bisa ditentukan dengan sizeof. Sebagai contoh:

double real[ 22 ];
Variabel dengan tipe data double secara normal disimpan di memori 8 bit. Jadi array real totalnya akan disimpan sebanyak 176 bit. Untuk menentukan jumlah dari elemen array, bisa menggunakan ekspresi : sizeof( real ) / sizeof( real[ 0 ] )

Fungsi getSize mengembalikan tipe size_t. Tipe size_t didefinisika di C sebagai tipe integral dari nilai pengembalian yang dilakukan oleh sizeof. Tipe size_t didefinisikan pada header <stddef.h> (yang di dalamnya ada beberapa header, antara lain <stdio.h>).

Bubble Sort Using Call-by-Reference

Fungsi bubbleSort berguna untuk mengurutkan array. Memanggil fungsi swap untuk menukarkan elemen array dari array[j] dan array[j+1]. Ingat bahwa program C akan memaksa untuk menyembunyikan  informasi diantara fungsi, agar array tidak bisa mengakses elemen individu di fungsi bubbleSort.
bubbleSort menggunakan alamat operator(&) di setiap elemen array yang di panggil swap.
     swap( &array[ j ], &array[ j + 1 ] );
Fungsi swap menerima array[j] di variable pointer element1Ptr. Meskipun swap tidak boleh mengetahui nama array[j], swap boleh menggunakan *element1Ptr sebagai ganti array[j].
Meskipun swap tidak diijinkan untuk menuliskan :
     hold = array[ j ];
     array[ j ] = array[ j + 1 ];
     array[ j + 1 ] = hold;
tetapi bisa digantikan :
     int hold = *element1Ptr;
     *element1Ptr = *element2Ptr;
     *element2Ptr = hold;

Contoh program:
1 /* Fig. 7.15: fig07_15.c
2 This program puts values into an array, sorts the values into
3 ascending order, and prints the resulting array. */
4 #include <stdio.h>
5 #define SIZE 10
6
7 void bubbleSort( int * const array, const int size ); /* prototype */
8
9 int main( void )
10 {
11 /* initialize array a */
12 int a[ SIZE ] = { 2, 6, 4, 8, 10, 12, 89, 68, 45, 37 };
13
14 int i; /* counter */
15
16 printf( "Data items in original order\n" );
17
18 /* loop through array a */
19 for ( i = 0; i < SIZE; i++ ) {
20 printf( "%4d", a[ i ] );
21 } /* end for */
22
23 bubbleSort( a, SIZE ); /* sort the array */
24
25 printf( "\nData items in ascending order\n" );
26
27 /* loop through array a */
28 for ( i = 0; i < SIZE; i++ ) {
29 printf( "%4d", a[ i ] );
30 } /* end for */
31
32 printf( "\n" );
33 return 0; /* indicates successful termination */
34 } /* end main */
35
36 /* sort an array of integers using bubble sort algorithm */
37 void bubbleSort( int * const array, const int size )
38 {
39 void swap( int *element1Ptr, int *element2Ptr ); /* prototype */
40 int pass; /* pass counter */
41 int j; /* comparison counter */
42
43 /* loop to control passes */
44 for ( pass = 0; pass < size - 1; pass++ ) {
45
46 /* loop to control comparisons during each pass */
47 for ( j = 0; j < size - 1; j++ ) {
48
49 /* swap adjacent elements if they are out of order */
50 if ( array[ j ] > array[ j + 1 ] ) {
51 swap( &array[ j ], &array[ j + 1 ] );
52 } /* end if */
53 } /* end inner for */
54 } /* end outer for */
55 } /* end function bubbleSort */

/* swap values at memory locations to which element1Ptr and
 element2Ptr point */
void swap( int *element1Ptr, int *element2Ptr )
{
 int hold = *element1Ptr;
 *element1Ptr = *element2Ptr;
 *element2Ptr = hold;
} /* end function swap */


Output:

Using the const Qualifier with Pointers

Const quailifier memungkinkan kita untuk menginformasikan pada compiler agar nilai dari suatu variable tertentu tidak boleh diubah. Pada kode program C versi awal-awal, const tidak digunakan karena tidak tersedia.

*Mengkonversi string ke huruf besar menggunakan non-constant pointer ke non-constant data
Level tertinggi dari akses data diberikan oleh pointer non-konstan untuk data non-konstan. Pada bagian ini data bisa diubah melalui pointer yang berbeda, dan pointer bisa diubah untuk menunjuk ke item data lain. Deklarasi pointer non-konstan ke data non-konstan tidak berisi  const. Pointer bisa digunakan untuk menerima string sebagai argumen untuk fungsi yang menggunakan pointer aritmatika untuk memproses (dan merubah jika mungkin) setiap karakter string. Fungsi convertToUppercase pada fig 7.10 mendeklarasikan parameter, non-konstan pointer ke non-konstan data yang dipanggil sPtr (char *sPtr), di baris ke 21.
Contoh Program:

1 /* Fig. 7.10: fig07_10.c
2 Converting a string to uppercase using a
3 non-constant pointer to non-constant data */
4
5 #include <stdio.h>
6 #include <ctype.h>
7
8 void convertToUppercase(char *sPtr); /* prototype */
9
10 int main( void )
11 {
12 char string[] = "characters and $32.98"; /* initialize char array */
13
14 printf( "The string before conversion is: %s", string );
15 convertToUppercase( string );
16 printf( "\nThe string after conversion is: %s\n", string );
17 return 0; /* indicates successful termination */
18 } /* end main */
19
20 /* convert string to uppercase letters */
21 void convertToUppercase(char *sPtr)
22 {
23 while (*sPtr != '\0' ) { /* current character is not '\0' */
24
25 if (islower( *sPtr )) { /* if character is lowercase, */
26 *sPtr = toupper( *sPtr ); /* convert to uppercase */
27 } /* end if */
28
29 ++sPtr; /* move sPtr to the next character */
30 } /* end while */
31 } /* end function convertToUppercase */


Output program: 

*Menampilkan satu karakter string menggunakan  pointer non-konstan ke data konstan.

Pointer non-konstan ke data konstan dapat dimodifikasi untuk tujuan ke beberapa item data dari jenis yang sesuai, tapi data yang dituju tidak dapat dimodifikasi. Pointer bisa menerima argument array yang akan memproses setiap elemen tanpa merubah data. Sebagai contoh, fungsi printCharacters mendeklarasikan parameter sPtr ke tipe const char *. Deklarasi dibaca dari kanan ke kiri sebagai “sPtr adalah pointer ke konstan karakter”. Fungsi menggunakan perintah for untuk menampilkan setiap karakter di string sampai mendapatkan nilai null.

/* Fig. 7.11: fig07_11.c
Printing a string one character at a time using
a non-constant pointer to constant data */
#include <stdio.h>
void printCharacters(const char *sPtr );
int main( void )
{
/* initialize char array */
char string[] = "print characters of a string";
printf( "The string is:\n" );
printCharacters( string );
printf( "\n" );
return 0; /* indicates successful termination */
} /* end main */
/* sPtr cannot modify the character to which it points,
i.e., sPtr is a "read-only" pointer */
void printCharacters( const char *sPtr )
{
/* loop through entire string */
for ( ; *sPtr != '\0'; sPtr++ ) { /* no initialization */
 printf( "%c", *sPtr );
} /* end for */
} /* end function printCharacters */

Output: 


Passing Argumen to Fungsi with Reference

Semua argumen di C tersebut diteruskan oleh nilai .
C menyediakan kemampuan untuk simulasi call-by - reference menggunakan pointer dan operator indirection.Untuk melewati sebuah variabel dengan reference , terapkan operator alamat ( & ) pada nama variabel .
Ketika alamat dari variabel dilewatkan ke fungsi, operator indirection ( * ) dapat digunakan dalam fungsi untuk mengubah nilai di lokasi tersebut dalam memori pemanggil . Fungsi yang menerima alamat sebagai argumen harus menentukan parameter pointer untuk menerima alamat . Compiler tidak membedakan antara fungsi yang menerima pointer dan fungsi yang menerima array tunggal - subscript . Sebuah fungsi harus mengetahui  ketika itu menerima sebuah array atau  satu variabel yang dilewatkan dengan reference . Ketika compiler bertemu dengan parameter fungsi untuk array tunggal subscript dalam bentuk int b [ ] , compiler mengubah parameter ke notasi pointer int * b .

Contoh 1:

/* Fig. 7.6: fig07_06.c
 Cube a variable using call-by-value */
 #include <stdio.h>

int cubeByValue( int n ); /* prototype */

int main( void )
 {
    int number = 5; /* initialize number */

     printf( "The original value of number is %d", number );

      /* pass number by value to cubeByValue */
      number = cubeByValue( number );

      printf( "\nThe new value of number is %d\n", number );
      return 0; /* indicates successful termination */
} /* end main */

/* calculate and return cube of integer argument */
int cubeByValue( int n )
{
return n * n * n; /* cube local variable n and return result */
} /* end function cubeByValue */

Output: 


Contoh 2:
/* Fig. 7.7: fig07_07.c
 Cube a variable using call-by-reference with a pointer argument */

#include <stdio.h>

void cubeByReference( int *nPtr ); /* prototype */
int main( void )
 {
   int number = 5; /* initialize number */

    printf( "The original value of number is %d", number );

     /* pass address of number to cubeByReference */
     cubeByReference( &number );

      printf( "\nThe new value of number is %d\n", number );
      return 0; /* indicates successful termination */
 } /* end main */

/* calculate cube of *nPtr; modifies variable number in main */
void cubeByReference( int *nPtr )
{
*nPtr = *nPtr * *nPtr * *nPtr; /* cube *nPtr */
} /* end function cubeByReference */

Output:

Operator Pointer

The & , atau operator alamat , adalah operator unary yang mengembalikan alamat dari operand. Operand dari operator alamat harus variabel .
Contoh:
Int y= 5;
Int *yPtr;
Strtmentnya:
yPtr =&y;
Representasi graphical dari pointer ke variabel integer dalam memori.
Operator indirection atau operator dereferencing  mengembalikan nilai dari objek ke yang mana poin operannya,contohnya:
printf(“%d”, *yPtr );
Konversi printf specifier % p output lokasi memori sebagai integer heksadesimal pada kebanyakan platform .
Contoh program:

/* Fig. 7.4: fig07_04.c
Using the & and * operators */
#include <stdio.h>

int main( void )
 {
    int a; /* a is an integer */
    int *aPtr; /* aPtr is a pointer to an integer */

   a = 7;
   aPtr = &a; /* aPtr set to address of a */

    printf( "The address of a is %p"
       "\nThe value of aPtr is %p",&a,aPtr );

    printf( "\n\nThe value of a is %d"
        "\nThe value of *aPtr is %d", a,*aPtr );

    printf( "\n\nShowing that * and & are complements of "
         "each other\n&*aPtr = %p"
        "\n*&aPtr = %p\n", &*aPtr ,*&aPtr );
    return 0; /* indicates successful termination */
 } /* end main */

Output: 

Definisi Pointer Variabel dan Inisialisasi

Sebuah pointer berisi alamat dari variabel lain yang mengandung nilai. Dalam hal ini , variabel
nama directly mengacu nilai , dan pointer indirectly mengacu nilai.

Pointer seperti semua variabel, harus didefinisikan sebelum digunakan ,contohnya:
int *countPtr, count

Mengacu nilai melalui pointer disebut indirection . Pointer dapat didefinisikan untuk menunjuk ke objek dari jenis apa pun . Pointer harus diinisialisasi baik ketika mereka sedang didefinisikan atau dalam pernyataan penugasan .



Sebuah pointer dapat diinisialisasi ke NULL , 0 atau sebuah alamat . Sebuah pointer dengan nilai poin NULL tidak menujukkan apa-apa .Menginisialisasi sebuah  pointer ke 0 adalah setara dengan menginisialisasi pointer ke NULL ,tetapi  NULL lebih disukai . Nilai 0 adalah satu-satunya nilai integer yang dapat diberikan langsung ke variabel pointer .
NULL adalah konstanta simbolis didefinisikan dalam header <stddef.h> ( dan beberapa header lain).

Jumat, 09 Mei 2014

Searching Arrays & Multiple-Subscripted Arrays

6.8 Searching Arrays
Searching : Proses untuk menemukan element dari array. Dalam searching itu dilakukan dengan cara membandingkan setiap array dengan menggunakan kata kunci tertentu. Di Linier Searching digunakan di array kecil atau unsorted array. Untuk sorted arrays, teknik pencarian biner tersebut highspeed. Searching binear jumlah maximum yang digunakan didalam array itu bisa terserah kita dengan ditentukan dengan menemukan fistpower dari 2 lebih besar dari jumlah element array.

6.9 Multiple-Subscripted Arrays
Multiple – subscript array digunakan untuk mewakili tabel nilai – nilai yang terdiri dari informasi yang diatur didalam inrows dan kolom unutk menngidentifikasi par-Terminologi 239 element yang mempunyai tabel khusus. Tabel atau array pasti membutuhkan 2 subcsript untuk mengetahui elemnt tertentu dari sebuah array yang berganda subscript.
Mutiple-Subscript dapat memiliki lebih dari 2 subscript.

Compiler menggunakan subcript untuk menentukan lokasi dalam memori element didalam Mutiple-Subscript. Diberi nilai Subscript didalam deklarasi parameter memberitau complier untuk memberitau funsi mencari element didalam array. 

Sorting Array

Sorting data adalah salah satu aplikasi komputasi yang paling penting. Sorting data pada kehidupan nyata memiliki peran yang besar, salah satunya bank memilah semua cek melalui akun nomor sehingga dapat mempersiapkan laporan bank pada akhir setiap bulan. Contoh yang lain adalah telepon perusahaan mengurutkan daftar mereka dari rekening dengan nama terakhir dan dengan nama pertama untuk membuatnya mudah untuk menemukan nomor telepon.

Pertama program membandingkan [ 0 ] ke [ 1 ] , maka [ 1 ] ke [ 2 ] , kemudian [ 2 ] ke [3], dan seterusnya sampai [ 8 ] ke [ 9 ]. Meskipun ada 10 elemen namun angka di dalam array hanya menunjukkan sampai angka 9 karena elemen pertama dimulai dengan array 0. Jika swap itu dilakukan oleh tiga tugas
hold = a[ i ];
a[ i ] = a[ i + 1 ];
a[ i + 1 ] = hold;
di mana variabel ekstra menyimpan sementara salah satu dari dua nilai, swap itu tidak dapat dilakukan dengan hanya dua tugas. 

Passing Arrays to Functions

Sebagai contoh, biasanya array didefinisikan sebagai berikut:
                int hourlyTemperatures[ 24 ];
lalu fungsi memanggil:
modifyArray( hourlyTemperatures, 24 )
fungsi modifyArray melewatkan array hourlyTemperatures dan size nya.

Program yang akan ditulis dibawah ini menjelaskan alamat asli dari elemen pertama array dengan menuliskan array, &array[0], &array menggunakan %p, yaitu konversi special untuk menunjukan alamat dari sebuah array.

/* Fig. 6.12: fig06_12.c
The name of an array is the same as &array[ 0 ] */
#include <stdio.h>
/* function main begins program execution */
int main( void )
{
     char array[ 5 ]; /* define an array of size 5 */
     printf( " array = %p\n&array[0] = %p\n &array = %p\n", array, &array[ 0 ], &array );
     return 0; /* indicates successful termination */
} /* end main */


Output: