Coding Styles and Obfuscated Programming

Hai readers,
pernah kedapetan kode program yang ditulis kayak gini gak ?

#include <stdio.h> /*Program penukaran dua variabel*/
void tukar(int* x, int* y){
int temp=*x;
*x=*y;
*y=temp;
}
int main(){
int a=5;
int b=7;
printf("a=%d\n",a);
printf("b=%d\n",b);
tukar(&a,&b); //terjadi penukaran
printf("..Setelah penukaran..\n");
printf("a=%d\n",a);
printf("b=%d\n",b);
}

Waktu pertama kali diliat, mungkin ada beberapa orang yang mengerti maksud kode di atas, tapi tidaklah banyak. Kita sebagai programmer yang baik harus membuat kode kita readable atau dapat dibaca dan dipahami. Coba bandingkan kode di atas dengan kode di bawah ini.

/**
 *
 * Program penukaran dua variabel
 * dengan menggunakan sub-program.
 */

#include <stdio.h>

void tukar(int* x, int* y)
{
    int temp = *x;
    *x = *y;
    *y = temp;
}

int main()
{
    // deklarasi dan inisialisasi variabel
    int a = 5;
    int b = 7;

    // variabel sebelum tertukar
    printf("a = %d\n", a);
    printf("b = %d\n", b);

    tukar(&a, &b); //terjadi penukaran

    printf("..Setelah penukaran..\n");

    // variabel setelah tertukar
    printf("a = %d\n", a);
    printf("b = %d\n", b);
}

A lot more readable, right ?
Ini ada beberapa perbandingan gaya penulisan kode yang disarankan

Variabel:
// Disarankan

int x = 5;

// Tidak disarankan

int x=5;

Function call:
// Disarankan

printf("x = %d", x);

// Tidak disarankan

printf("x=%d\n",x);

Operator dan operand:
// Disarankan

z = x + (y * 2);

// Tidak disarankan

z=x+y*2;

Scope spacing:
// Disarankan

void sub1()
{
   //TODO
}

void sub2()
{
   //TODO
}

// Tidak disarankan

void sub1()
{
   //TODO
}
void sub2()
{
   //TODO
}

Scope indentation:
// Disarankan

int main()
{
   int x = 5;
   printf("x = %d\n", x);
}

// Tidak disarankan

int main()
{
int x=5;
printf("x=%d\n",x);
}


Tapi dari semua perbandingan kode di atas, ada loh orang yang menulis kode program dengan gaya yang unik. Contohnya seperti ini.

#include                                     <math.h>
#include                                   <sys/time.h>
#include                                   <X11/Xlib.h>
#include                                  <X11/keysym.h>
                                          double L ,o ,P
                                         ,_=dt,T,Z,D=1,d,
                                         s[999],E,h= 8,I,
                                         J,K,w[999],M,m,O
                                        ,n[999],j=33e-3,i=
                                        1E3,r,t, u,v ,W,S=
                                        74.5,l=221,X=7.26,
                                        a,B,A=32.2,c, F,H;
                                        int N,q, C, y,p,U;
                                       Window z; char f[52]
                                    ; GC k; main(){ Display*e=
 XOpenDisplay( 0); z=RootWindow(e,0); for (XSetForeground(e,k=XCreateGC (e,z,0,0),BlackPixel(e,0))
; scanf("%lf%lf%lf",y +n,w+y, y+s)+1; y ++); XSelectInput(e,z= XCreateSimpleWindow(e,z,0,0,400,400,
0,0,WhitePixel(e,0) ),KeyPressMask); for(XMapWindow(e,z); ; T=sin(O)){ struct timeval G={ 0,dt*1e6}
; K= cos(j); N=1e4; M+= H*_; Z=D*K; F+=_*P; r=E*K; W=cos( O); m=K*W; H=K*T; O+=D*_*F/ K+d/K*E*_; B=
sin(j); a=B*T*D-E*W; XClearWindow(e,z); t=T*E+ D*B*W; j+=d*_*D-_*F*E; P=W*E*B-T*D; for (o+=(I=D*W+E
*T*B,E*d/K *B+v+B/K*F*D)*_; p<y; ){ T=p[s]+i; E=c-p[w]; D=n[p]-L; K=D*m-B*T-H*E; if(p [n]+w[ p]+p[s
]== 0|K <fabs(W=T*r-I*E +D*P) |fabs(D=t *D+Z *T-a *E)> K)N=1e4; else{ q=W/K *4E2+2e2; C= 2E2+4e2/ K
 *D; N-1E4&& XDrawLine(e ,z,k,N ,U,q,C); N=q; U=C; } ++p; } L+=_* (X*t +P*M+m*l); T=X*X+ l*l+M *M;
  XDrawString(e,z,k ,20,380,f,17); D=v/l*15; i+=(B *l-M*r -X*Z)*_; for(; XPending(e); u *=CS!=N){
                                   XEvent z; XNextEvent(e ,&z);
                                       ++*((N=XLookupKeysym
                                         (&z.xkey,0))-IT?
                                         N-LT? UP-N?& E:&
                                         J:& u: &h); --*(
                                         DN -N? N-DT ?N==
                                         RT?&u: & W:&h:&J
                                          ); } m=15*F/l;
                                          c+=(I=M/ l,l*H
                                          +I*M+a*X)*_; H
                                          =A*r+v*X-F*l+(
                                          E=.1+X*4.9/l,t
                                          =T*m/32-I*T/24
                                           )/S; K=F*M+(
                                           h* 1e4/l-(T+
                                           E*5*T*E)/3e2
                                           )/S-X*d-B*A;
                                           a=2.63 /l*d;
                                           X+=( d*l-T/S
                                            *(.19*E +a
                                            *.64+J/1e3
                                            )-M* v +A*
                                            Z)*_; l +=
                                            K *_; W=d;
                                            sprintf(f,
                                            "%5d  %3d"
                                            "%7d",p =l
                                           /1.7,(C=9E3+
                              O*57.3)%0550,(int)i); d+=T*(.45-14/l*
                             X-a*130-J* .14)*_/125e2+F*_*v; P=(T*(47
                             *I-m* 52+E*94 *D-t*.38+u*.21*E) /1e2+W*
                             179*v)/2312; select(p=0,0,0,0,&G); v-=(
                              W*F-T*(.63*m-I*.086+m*E*19-D*25-.11*u
                               )/107e2)*_; D=cos(o); E=sin(o); } }


#define _ -F<00||--F-OO--;
int F=00,OO=00;main(){F_OO();printf("%1.3f\n",4.*-F/OO/OO);}F_OO()
{
            _-_-_-_
       _-_-_-_-_-_-_-_-_
    _-_-_-_-_-_-_-_-_-_-_-_
  _-_-_-_-_-_-_-_-_-_-_-_-_-_
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
  _-_-_-_-_-_-_-_-_-_-_-_-_-_
    _-_-_-_-_-_-_-_-_-_-_-_
        _-_-_-_-_-_-_-_
            _-_-_-_
}

Gaya penulisan kode seperti itu dinamakan Obfuscated Programming. Yaitu penulisan kode agar maksud dari kode tersebut susah untuk ditebak.



Sekian dulu, semoga kita dapat menulis kode yang lebih indah dan readable.

Konsep Array atau Larik



Beberapa cara pendeklarasian array:

int nilai[4] = {2, 4, 3, 7};


int nilai[] = {2, 4, 3, 7};


int nilai[4];
nilai[0] = 2;
nilai[1] = 4;
nilai[2] = 3;
nilai[3] = 7;

Untuk tipe data char,
Tanpa array:
char huruf = 'A';

Dengan array:

char kata[6] = {'A', 'z', 'h', 'a', 'r', 'y'};


char kata[6] = "Azhary";


char kata[] = "Azhary";

Ingat! Array of char = string.

Cara menampilkan string ke layar:
#include <stdio.h>

int main()
{
   char kata[] = "Azhary";
   printf("Nama = %s", kata);
   return 0;
}

Menampilkan huruf ke-2 pada variabel kata:
printf("%c", kata[1]);

Multi-dimensional Array,
char kalimat[2][15] = {"Azhary", "Arliansyah"};

Menampilkan kata "Azhary" pada variabel kalimat:
printf("%s", kalimat[0]);

..(!! Array adalah Pointer !!)..
*kata == kata[0]

*(kata + 1) == kata[1]

Contoh source code:
#include <stdio.h>

int main()
{
    int x[2];
    x[1] = 1;

    if (*(x + 1) == x[1])
    {
        printf("Sama\n");
    }

    return 0;
}

Fungsi dan Prosedur (Part 2)



Disini kita akan memperjelas apa itu fungsi dan prosedur. Langsung saja...

Fungsi (mempunyai return value)
int angka()
{
   int x = 5;
   return x;
}

Prosedur (tidak mempunyai return value)
void angka()
{
   int x = 5;
}

atau

void angka()
{
   int x = 5;
   return;
}

Prosedur dengan parameter:
void tukar(int x, int y)
{
   int temp = x;
   x = y;
   y = temp;
}

Fungsi dengan parameter:
int tambah(int x, int y)
{
   return x + y;
}

Variabel pada prosedur hanya bisa digunakan di dalam prosedur itu dan tidak bisa digunakan di luar prosedur. Lebih jelas tentang ini silahkan baca konsep Scope.

Fungsi dan prosedur hanya bisa dijalankan di main() sehingga kita harus memanggil fungsi/prosedur tersebut ke dalam fungsi main seperti ini.
Pemanggilan fungsi ber-parameter:
#include <stdio.h>

int tambah(int x, int y)
{
   return x + y;
}

int main()
{
   int hasil = tambah(4, 6);
   printf("Hasil = %d\n", hasil);
   return 0;
}

atau

#include <stdio.h>

int tambah(int x, int y)
{
   return x + y;
}

int main()
{
   printf("Hasil = %d\n", tambah(4, 6));
   return 0;
}




Pengulangan dengan Do - While Loop



Kerangka do-while:
do
{
   /* statement */
}
while (/* condition */);

Contoh source code:
#include <stdio.h>

int main()
{
   int i = 0;
   
   do
   {
      printf("Hello world %d\n", i);
      i++; // counter agar kondisi tidak selalu bernilai benar
   }
   while (i < 5);

   return 0;
}

Pengulangan dengan While Loop


Kerangka while:
while (/* condition */)
{
    /* statement */
}

Contoh source code:
#include <stdio.h>

int main()
{
   int i = 0;
   
   while (i < 5)
   {
      printf("Hello world %d\n", i);
      i++; // counter agar kondisi tidak selalu bernilai benar
   }

   return 0;
}

Pengulangan dengan For Loop



Kerangka for:
for (/* start */; /* condition */ ; /* counter */)
{
    /* statement */
}

Contoh source code:
#include <stdio.h>

int main()
{
   for (int i = 0; i < 5; i++)
   {
      printf("Hello world %d\n", i);
   }

   return 0;
}

atau

#include <stdio.h>

int main()
{
   int i;

   for (i = 0; i < 5; i++)
   {
      printf("Hello world %d\n", i);
   }

   return 0;
}

Perkondisian dengan Switch - Case Statement





Kerangka switch - case:
switch (/* variabel */)
{
    case value1:
           /* first statement */
           break;
    case value2:
           /* second statement */
           break;
    default:
           /* last statement */
           break;
}

Contoh source code:
int main()
{
   int opsi;
 
   printf("Menu:\n1. Nasi Goreng\n2. Mie Ayam\n");
   printf("Pilihan: ");
   scanf("%d", &opsi);

   switch (opsi)
   {
      case 1: 
           printf("Kamu memilih nasi goreng\n");
           break;
      case 2:
           printf("Kamu memilih mie ayam\n");
           break;
      default:
           printf("Pilihanmu tidak ada di dalam menu\n");
           break;
   }

   return 0;
}

Perkondisian dengan 'If - Else If - Else' Statement





Kerangka if:
if (/* condition */)
{
   /* statement */
}

Kerangka if - else:
if (/* condition */)
{
   /* statement */
}
else
{
   /* another statement */
}

Kerangka if - else if - else:
if (/* condition */)
{
   /* first statement */
}
else if (/* another condition */)
{
   /* second statement */
}
else
{
   /* last statement */
}


Contoh source code:
#include <stdio.h>

int main()
{
   int opsi;
 
   printf("Menu:\n1. Nasi Goreng\n2. Mie Ayam\n");
   printf("Pilihan: ");
   scanf("%d", &opsi);

   if (opsi == 1)
   {
      printf("Kamu memilih nasi goreng\n");
   }
   else if (opsi == 2)
   {
      printf("Kamu memilih mie ayam\n");
   }
   else
   {
      printf("Pilihanmu tidak ada di dalam menu\n");
   }

   return 0;
}

Input/Output Penjumlahan Dua Variabel



Fungsi input:
scanf("..",..);

Example:
scanf("%d", &x);


Fungsi output:
printf("..",..);

Example:
printf("%d", x);


Kedua fungsi tersebut terdapat di library:
#include <stdio.h>


Contoh source code:
#include <stdio.h>

int main()
{
   int x;
   int y;

   printf("Masukkan nilai x: ");
   scanf("%d", &x);
   printf("Masukkan nilai y: ");
   scanf("%d", &y);

   printf("x + y = %d", x + y);

   return 0;
}

Jenis placeholder:
%d, %i         int
%f             float
%c             char
%s             string(char* or char[])
%li            long int
.
.
etc.

Konsep Scope pada Pemrograman C

Hloww...

Disini kita akan mempelajari tentang Scope. Sesuai katanya, Scope berarti ruang lingkup.
Scope terbagi jadi dua, global dan local.

Langsung saja ke contoh.

#include <stdio.h>

int glb = 5;

void tambah()
{
   int x = glb + 5;
   printf("x = %d\n", x);
}

int main()
{
   tambah();
   return 0;
}

Compile & run, maka outputnya akan begini.

Deskripsi:
Program tersebut memiliki sebuah variabel global glb  dan sebuah variabel lokal x. Variabel glb bersifat global karena 1. Tidak berada di dalam main atau sub-program, 2. Variabel tersebut dapat diakses pada sub-program manapun, contohnya dapat dipakai untuk ditampilkan pada sub-program tambah(). Sedangkan x bersifat lokal karena hanya dapat diakses pada sub-program tambah() dan tidak dapat diakses pada sub-program yang lain, jika "memaksa" ingin menampilkan nilai x pada main() seperti ini.

int main()
{
   tambah();
   printf("nilai x = %d", x);
   return 0;
}

maka program tersebut akan error: 'x' undeclared (first use in this function).

Lalu, gimana caranya kita "bermain" dengan konsep Scope ini? Caranya adalah dengan menggunakan pointer. Perhatikan kode berikut.

#include <stdio.h>

void tukar(int x, int y)
{
    int temp = x;
    x = y;
    y = temp;
}

int main()
{
    int a = 5;
    int b = 7;

    printf("a = %d\n", a);
    printf("b = %d\n", b);

    tukar(a, b);
    printf("..Setelah penukaran..\n");

    printf("a = %d\n", a);
    printf("b = %d\n", b);
}

Program tersebut menukarkan angka pada variabel a dan b, tapi penukaran tidak terjadi, karena fungsi penukaran hanya bersifat lokal pada sub-program tukar().


Tapi, jika kodenya kita ubah sedikit tanpa menggunakan sub-program seperti ini.

#include <stdio.h>

int main()
{
    int a = 5;
    int b = 7;

    printf("a = %d\n", a);
    printf("b = %d\n", b);

    int temp = a;
    a = b;
    b = temp;
    printf("..Setelah penukaran..\n");

    printf("a = %d\n", a);
    printf("b = %d\n", b);
}

maka penukaran pun terjadi.


Supaya kita dapat membuat fungsi penukaran yang dapat digunakan pada fungsi yang lain(dalam kasus ini main()), maka kita dapat menggunakan pointer seperti ini.

#include <stdio.h>

void tukar(int* x, int* y)
{
    int temp = *x;
    *x = *y;
    *y = temp;
}

int main()
{
    int a = 5;
    int b = 7;

    printf("a = %d\n", a);
    printf("b = %d\n", b);

    tukar(&a, &b);
    printf("..Setelah penukaran..\n");

    printf("a = %d\n", a);
    printf("b = %d\n", b);
}

Magic happens! penukaran pun terjadi.

Itu dapat terjadi karena kita bukan menaruh nilai variabel a dan b pada parameter fungsi tukar(), tapi kita menaruh alamat memori variabel a dan b. Lalu nilai pada alamat memori a dan b tersebut akan di-load pada main().

Here is our conclusion in picture!

Membuat Kode Program di Blog Berwarna seperti di IDE

Oke, sesuai judul, langsung saja...

Pertama klik link berikut.

http://tohtml.com/
 Lalu pada kotak Type pilih main: C.


Kemudian, pada kotak Source code ketiklah kode program yang ingin "diberi warna" lalu klik tombol highlight


Biar mudah, copy saja kode yang ada di preview lalu paste ke blog.


#include <stdio.h>

int main(int argc, char* argv[])
{
   printf("Hello world");
   return 0;
}

Sekian, semoga bermanfaat :D

Pemrograman C di Linux

Hello readers,

Disini ane jelasin sedikit cara memprogram C di linux. Tools yang dipake yaitu.
1. Text Editor (disarankan pake gedit)
2. Terminal

Nah, sekarang coba kita buka text editor melalui terminal dengan format command seperti ini.

text_editor nama_file
 Contoh:

Kalo file yang bernama hello belum ada, maka akan dibuat file baru. Kalo udah ada, maka akan membuka file yang sudah ada tersebut. Dan jangan lupa ditambah .c dibelakang nama file kalo ingin memprogram dalam bahasa C.

Oke, dan sekarang di gedit, coba buat contoh program sederhana seperti biasa.

#include <stdio.h>

int main()
{
   printf("Hello world!");
   return 0;
}

Kemudian di-save, terus di-compile and run.... but wait, kok gak ada tombol compile-nya sih di gedit?
Gedit itu hanyalah text editor bukan IDE(Integrated Development Environment). So, gimana nge-compilenya ?
Buka lagi terminal, kemudian ketik.

gcc hello.c -o hello

Tekan enter, kemudian di-execute dengan mengetik

./hello

Voila! our first program in linux... 

Let us make another program!
Buka terminal, kemudian ketik.

gedit pengulangan.c
 Lalu buatlah program seperti ini.

#include <stdio.h>

int main()
{
  for (int i = 0; i < 5; i++)
  {
     printf("Hello world!\n");
  }
  return 0;
}


Klik save, kemudian ketik lagi seperti yang diatas namun kali ini kita pake operator &&(dan) untuk menggabung dua command seperti ini

gcc pengulangan.c -o pengulangan && ./pengulangan
 Dan akan tampil seperti ini.

Oops, error. pengulangan tipe for hanya bisa dipake dalam mode c99. Gimana cara ubah ke mode c99? cukup dengan menambah -std=c99 saat nge-compile seperti ini.

gcc -std=c99 -o pengulangan pengulangan.c && ./pengulangan

Begitulah cara compile and run program di linux. Tapi kan rempong kalo ngetik panjang panjang kayak gcc blablabla tiap kita nge-compile program.

Kita gak perlu kok ngetik panjang kayak gitu tiap nge-compile program. Command kayak gitu cukup kita "bungkus" di dalam sebuah Makefile.
Caranya seperti ini, pertama buka gedit dan ketik.

CC = clang

CFLAGS = -std=c99 -Wall -Werror

Save as dengan nama Makefile tanpa .c dibelakangnya. Taruh file tersebut di dalam folder yang sama dengan source code yang lo buat.
Jadi, kalo ingin nge-compile program kita cukup mengetik di terminal kayak gini.

make pengulangan
Kemudian ketik.
./pengulangan


Voila! compiling program jadi lebih mudah.

Memprogram tanpa IDE emang agak sulit, tapi itu melatih ketelitian elo dalam coding, sehingga dapat mengurangi syntax error. Lagi pula gak cuma kesalahan sintaks yang bakal elo alami, pada materi struktur data lo bakal sering mengalami logic error dan kesalahan manajemen memori. Di linux kita bisa pake tool bernama valgrind untuk mengecek dimana memory leak yang kita buat. Juga ada tool bernama GNU Project Debugger(GDB) yang bisa kita gunakan untuk mengecek lebih dalam letak kesalahan logika program kita, tanpa harus membuang waktu mencari error dengan cara menebak-nebak.

Cara gunainnya nanti akan ane share di lain waktu :D
So, stay tuned!!