Minggu, 06 November 2016

Tips Agar Kode C Kamu Lebih Singkat dan Mudah Dibaca


Tulisan ini akan menyinggung beberapa catatan mengenai keterbacaan kode. Seperti halnya dengan proyek terbuka yang digarap secara ramai-ramai, biasanya kode akan dibuat agar mudah dibaca oleh orang lain. Sehingga kontributor baru pun akan cepat belajar dan paham tentang alur program yang sedang dikembangkan.
Meski source code tersebut telah tumbuh menjadi jutaan baris kode, ternyata kontributornya masih mood juga, ya. Kalau kita, mungkin akan menulis kode dari awal kali, ya. Apalagi kalau project tersebut sudah lama ditinggal, jadi lupa semuanya. hehehe

Berikut tips yang bisa kamu ikuti, jika kamu ingin mendaptakan hasil kodingan yang selalu membuat mood kamu ON.

Pertama, ketahui bahwa mengecek nilai bukan 0 bisa ditulis lebih sederhana. Daripada menulis seperti ini,
if(var != 0){
    //your code here
}


kamu bisa menggantinya jadi seperti ini,
if(var){
    //your code here
}


compiler akan mengerti dan mengartikan sebagai "jika var bukan 0"

Sama halnya jika ingin mengecek nilai 0,
if(var == 0){
    //your code here
}


Kamu bisa menambahkan operator not (!) dibelakangnya.
if(!var){
    //your code here
}


Bahkan kamu juga bisa mengecek hasil dari operasi statement,
if(var * 5 == 0){
    //your code here
}


dengan cukup menulis ini.
if(!(var * 5)){
    //your code here
}


compiler juga paham bahwa kamu sedang mengatakan "jika var dikali 5 adalah 0".

Selanjutnya, jika statemen dari perlakukan kondisi hanya memerlukan 1 baris kode,
if(condition){
    //your code here
}
else {
    //your code here
}


sebaiknya kamu lebih meringkasnya,
if(condition) //your code here
else //your code here


atau seperti ini; tanpa tab/spasi dibelakangnya juga boleh.
if(condition)
    //your code here
else
    //your code here


Sering kali semuah nilai memiliki makna tersirat. Angka satu buka cuma berarti 1, angka 99 bukan cuma berarti 99. Kadangkala nilai juga merepresentasikan suatu hal. Saat masuk dalam keadaan seperti ini, gunakan #define atau enum untuk memberikan makna pada nilai tersebut. Misalnya pada kasus berikut ini,
switch(hasil){
    case 0:
    printf("kepala");
    case 1:
    printf("badan");
    case 2:
    printf("kaki");
}
...
if(pilihan == 0)
    //lakukan sesuatu
else if(pilihan == 1)
    //lakukan sesuatu
else
    //lakukan sesuatu

   
sebaiknya kamu menerapkan #define pada setiap angka yang digunakan, sehingga kode akan lebih mudah dibaca.
#define KEPALA 0
#define BADAN 1
#define KAKI 2

switch(hasil){
    case KEPALA:
    printf("kepala");
    case BADAN:
    printf("badan");
    case KAKI:
    printf("kaki");
}
...
if(pilihan == KEPALA)
    //lakukan sesuatu
else if(pilihan == BADAN)
    //lakukan sesuatu
else
    //lakukan sesuatu

   
Bukan cuma itu, keterbacaan kode juga bisa diperoleh dengan memberikan nilai standar pada return value, lho.
Menurut konsensus, biasanya fungsi yang normal akan mengembalikan nilai 0 atau positif. Begitu, sebaliknya ketika error.
int fungsi_a(arg){
    if(cond error invalid)
        return -1;
    if(cond error failed)
        return -2;
    if(cond error undefined)
        return -3;
    else if(cond normal)
        return 0;
}


Jadi, coba berikan nama pada tiap nilai yang merepresentasikan error saat diperlukan, seperti ini,
#define ERROR_INVALID -1
#define ERROR_FAILED -2
#define ERROR_UNDEFINED -3
#define NO_ERROR 0
int fungsi_a(arg){
    if(cond error invalid)
        return ERROR_INVALID;
    if(cond error failed)
        return ERROR_FAILED;
    if(cond error undefined)
        return ERROR_UNDEFINED;
    else if(condition normal)
        return NO_ERROR;
}


Lalu, kode untuk pengecekan error dapat dibuat lebih singkat dan mudah dibaca dengan macro. Jika sebelumnya kita harus pusing melihat simbol-simbol operator seperti ini,
int main(){
    int result = fungsi_a(arg);
    if(result == ERROR_INVALID || result == ERROR_FAILED || result == ERROR_UNDEFINED)
        //do something
}


coba sembunyikan kerumitan tersebut dengan fungsi macro yang disimpan dalam header. Bentuknya jadi seperti ini.
//my_program.h
#define IS_ERROR(value) (value == ERROR_INVALID || value == ERROR_FAILED || value == ERROR_UNDEFINED)



//my_program.c
int main(){
    int result = fungsi_a(arg);
    if(IS_ERROR(result))
        //do something
}


Selanjutnya juga bisa dimodifikasi lagi seperti ini,
#define IS_NOT_ERROR(value) (!(value == ERROR_INVALID || value == ERROR_FAILED || value == ERROR_UNDEFINED))
int main(){
    int result = fungsi_a(arg);
    if(IS_NOT_ERROR(result))
        //do something
}


Kalau kamu lebih suka bahasa Indonesia, dan pusing melihat bahasa inggris;
buffer = malloc(100);
strcpy(buffer,"abcde",5);


#define juga bisa membantumu.
#define ALOKASI malloc
#define SALIN_STRING strcpy
...
buffer = ALOKASI(100);
SALIN_STRING(buffer,"abcde",5);


Last, but not least. Macro juga bisa dipakai saat kode yang kamu tulis banyak mengulang-ulang beberapa baris kode serupa.
if(cond a){
    strupr(x);
    printf(x);
    free(x);
}
else if(cond b){
    strupr(y);
    printf(y);
    free(y);
}
if(cond c){
    strupr(z);
    printf(z);
    free(z);
}


Sekarang jadi lebih singkat, lho.
#define SPF(x) ( \
    strupr(x); \
    printf(x); \
    free(x); \
)

if(cond a)
    SPF(x);
else if(cond b)
    SPF(y);
if(cond c)
    SPF(z);


Sebenarnya masih ada tips lain yang belum saya sampaikan. Tapi, berhubung memori pikiran saya sudah mentok, mungkin dilanjutkan lain kali aja ya. :)
Load disqus comments

0 comments