Memahami Preprocessor C (CPP): Bagaimana Ini Mengompilasi
C Preprocessor bukan merupakan bagian dari kompiler, melainkan merupakan langkah terpisah dalam proses kompilasi. Dalam istilah sederhana, C Preprocessor hanyalah alat penggantian teks dan meminta kompiler untuk melakukan pre-pemrosesan yang diperlukan sebelum kompilasi sebenarnya. Kita akan menyebut C Preprocessor sebagai CPP.
Semua perintah preprocessor dimulai dengan simbol hash (#). Itu harus menjadi karakter non-kosong pertama, dan untuk keterbacaan, direktif preprocessor harus dimulai di kolom pertama. Bagian berikut mencantumkan semua direktif preprocessor penting −
| Sr.No. | Direktif & Deskripsi |
| 1 | #define Mengganti makro preprocessor. |
| 2 | #include Menyisipkan header tertentu dari file lain. |
| 3 | #undef Menghapus definisi makro preprocessor. |
| 4 | #ifdef Mengembalikan true jika makro ini didefinisikan. |
| 5 | #ifndef Mengembalikan true jika makro ini tidak didefinisikan. |
| 6 | #if Menguji apakah kondisi waktu kompilasi benar. |
| 7 | #else Alternatif untuk #if. |
| 8 | #elif #else dan #if dalam satu pernyataan. |
| 9 | #endif Mengakhiri kondisional preprocessor. |
| 10 | #error Mencetak pesan kesalahan pada stderr. |
| 11 | #pragma Mengeluarkan perintah khusus ke kompiler, menggunakan metode yang distandardisasi. |
Contoh Preprocessor
Analisis contoh-contoh berikut untuk memahami berbagai direktif.
#define MAX_ARRAY_LENGTH 20
Direktif ini memberi tahu CPP untuk mengganti instance MAX_ARRAY_LENGTH dengan 20. Gunakan #define untuk konstanta untuk meningkatkan keterbacaan.
#include <stdio.h> #include "myheader.h"
Direktif ini memberi tahu CPP untuk mengambil stdio.h dari System Libraries dan menambahkan teks ke file sumber saat ini. Baris berikutnya memberi tahu CPP untuk mengambil myheader.h dari direktori lokal dan menambahkan konten ke file sumber saat ini.
#undef FILE_SIZE #define FILE_SIZE 42
Ini memberi tahu CPP untuk menghapus definisi FILE_SIZE yang ada dan mendefinisikannya sebagai 42.
#ifndef MESSAGE #define MESSAGE "Anda berharap!" #endif
Ini memberi tahu CPP untuk mendefinisikan MESSAGE hanya jika MESSAGE belum didefinisikan.
#ifdef DEBUG /* Pernyataan debug Anda di sini */ #endif
Ini memberi tahu CPP untuk memproses pernyataan yang tertutup jika DEBUG didefinisikan. Ini berguna jika Anda meneruskan flag -DDEBUG ke kompiler gcc saat kompilasi. Ini akan mendefinisikan DEBUG, sehingga Anda dapat menghidupkan dan mematikan debugging secara langsung selama kompilasi.
Makro Terdefinisi
ANSI C mendefinisikan sejumlah makro. Meskipun masing-masing tersedia untuk digunakan dalam pemrograman, makro terdefinisi tidak boleh langsung dimodifikasi.
| Sr.No. | Makro & Deskripsi |
| 1 | __DATE__ Tanggal saat ini sebagai literal karakter dalam format "MMM DD YYYY". |
| 2 | __TIME__ Waktu saat ini sebagai literal karakter dalam format "HH:MM:SS". |
| 3 | __FILE__ Ini berisi nama file saat ini sebagai literal string. |
| 4 | __LINE__ Ini berisi nomor baris saat ini sebagai konstanta desimal. |
| 5 | __STDC__ Didefinisikan sebagai 1 ketika kompiler mematuhi standar ANSI. |
Mari kita coba contoh berikut −
Live Demo
#include <stdio.h> int main() { printf("File :%s\n", __FILE__ ); printf("Tanggal :%s\n", __DATE__ ); printf("Waktu :%s\n", __TIME__ ); printf("Baris :%d\n", __LINE__ ); printf("ANSI :%d\n", __STDC__ ); } Ketika kode di atas dalam file test.c dikompilasi dan dieksekusi, hasilnya adalah sebagai berikut −
File :test.c Tanggal :Jun 2 2012 Waktu :03:36:24 Baris :8 ANSI :1
Operator Preprocessor
C preprocessor menawarkan operator berikut untuk membantu membuat makro −
Operator Lanjutan Makro (\)
Sebuah makro biasanya terbatas pada satu baris. Operator lanjutan makro (\) digunakan untuk melanjutkan makro yang terlalu panjang untuk satu baris. Misalnya −
#define message_for(a, b) \ printf(#a " dan " #b ": Kami mencintaimu!\n")
Operator Stringize (#)
Operator stringize atau tanda pagar ('#'), ketika digunakan dalam definisi makro, mengonversi parameter makro menjadi konstanta string. Operator ini hanya dapat digunakan dalam makro yang memiliki daftar argumen atau parameter yang ditentukan. Misalnya −
Live Demo
#include <stdio.h> #define message_for(a, b) \ printf(#a " dan " #b ": Kami mencintaimu!\n") int main(void) { message_for(Carole, Debra); return 0; } Ketika kode di atas dikompilasi dan dieksekusi, hasilnya adalah sebagai berikut −
Carole dan Debra: Kami mencintaimu!
Operator Token Pasting (##)
Operator token-pasting (##) dalam definisi makro menggabungkan dua argumen. Ini memungkinkan dua token terpisah dalam definisi makro untuk digabungkan menjadi satu token. Misalnya −
Live Demo
#include <stdio.h> #define tokenpaster(n) printf ("token" #n " = %d", token##n) int main(void) { int token34 = 40; tokenpaster(34); return 0; } Ketika kode di atas dikompilasi dan dieksekusi, hasilnya adalah sebagai berikut −
token34 = 40
Ini terjadi karena contoh ini menghasilkan output aktual berikut dari preprocessor −
printf ("token34 = %d", token34); Contoh ini menunjukkan penggabungan token##n menjadi token34 dan di sini kita telah menggunakan baik stringize dan token-pasting.
Operator Defined()
Operator preprocessor defined digunakan dalam ekspresi konstan untuk menentukan apakah pengidentifikasi didefinisikan menggunakan #define. Jika pengidentifikasi yang ditentukan didefinisikan, nilainya benar (non-nol). Jika simbol tidak didefinisikan, nilainya salah (nol). Operator defined ditentukan sebagai berikut −
Live Demo
#include <stdio.h> #if !defined (MESSAGE) #define MESSAGE "Anda berharap!" #endif int main(void) { printf("Di sini adalah pesan: %s\n", MESSAGE); return 0; } Ketika kode di atas dikompilasi dan dieksekusi, hasilnya adalah sebagai berikut −
Di sini adalah pesan: Anda berharap!
Makro Berparameter
Salah satu fungsi canggih dari CPP adalah kemampuan untuk mensimulasikan fungsi menggunakan makro berparameter. Misalnya, kita mungkin memiliki beberapa kode untuk mengkuadratkan angka sebagai berikut −
int square(int x) { return x * x; } Kita dapat menulis ulang kode di atas menggunakan makro sebagai berikut −
#define square(x) ((x) * (x))
Makro dengan argumen harus didefinisikan menggunakan direktif #define sebelum dapat digunakan. Daftar argumen diapit dalam tanda kurung dan harus segera mengikuti nama makro. Spasi tidak diperbolehkan antara nama makro dan tanda kurung buka. Misalnya −
Live Demo
#include <stdio.h> #define MAX(x,y) ((x) > (y) ? (x) : (y)) int main(void) { printf("Max antara 20 dan 10 adalah %d\n", MAX(10, 20)); return 0; } Ketika kode di atas dikompilasi dan dieksekusi, hasilnya adalah sebagai berikut −
Max antara 20 dan 10 adalah 20