C prapemproses


Prapemproses C bukan sebahagian daripada pengkompil, tetapi merupakan langkah berasingan dalam proses penyusunan. Secara ringkasnya, prapemproses C tidak lebih daripada alatan penggantian teks yang mengarahkan pengkompil untuk melengkapkan prapemprosesan yang diperlukan sebelum penyusunan sebenar. Kami akan menyingkat C Preprocessor sebagai CPP.

Semua arahan prapemproses bermula dengan tanda paun (#). Ia mestilah aksara bukan nol pertama, dan untuk meningkatkan kebolehbacaan, arahan prapemproses harus bermula dari lajur pertama. Semua arahan prapemproses penting disenaraikan di bawah:

指令描述
#define定义宏
#include包含一个源代码文件
#undef取消已定义的宏
#ifdef如果宏已经定义,则返回真
#ifndef如果宏没有定义,则返回真
#if如果给定条件为真,则编译下面代码
#else#if 的替代方案
#elif如果前面的 #if 给定条件不为真,当前条件为真,则编译下面代码
#endif结束一个 #if……#else 条件编译块
#error当遇到标准错误时,输出错误消息
#pragma使用标准化方法,向编译器发布特殊的命令到编译器中

Contoh Prapemproses

Analisis contoh berikut untuk memahami arahan yang berbeza.

#define MAX_ARRAY_LENGTH 20

Arahan ini memberitahu CPP untuk menggantikan semua MAX_ARRAY_LENGTH dengan 20. Gunakan #define untuk menentukan pemalar bagi meningkatkan kebolehbacaan.

#include <stdio.h>#include "myheader.h"

Arahan ini memberitahu CPP untuk mendapatkan stdio.h daripada pustaka sistem dan menambah teks pada fail sumber semasa. Baris seterusnya memberitahu CPP untuk mendapatkan myheader.h daripada direktori tempatan dan menambah kandungan pada fail sumber semasa.

#undef  FILE_SIZE#define FILE_SIZE 42

Arahan ini memberitahu CPP untuk membatalkan FILE_SIZE yang ditentukan dan mentakrifkannya sebagai 42.

#ifndef MESSAGE   #define MESSAGE "You wish!"#endif

Arahan ini memberitahu CPP untuk mentakrifkan MESSAGE hanya jika MESSAGE tidak ditentukan.

#ifdef DEBUG   /* Your debugging statements here */#endif

Arahan ini memberitahu CPP untuk melaksanakan pernyataan pemprosesan jika DEBUG ditakrifkan. Arahan ini berguna jika anda melepasi suis -DDEBUG kepada pengkompil gcc pada masa penyusunan. Ia mentakrifkan DEBUG dan anda boleh menghidupkan atau mematikan nyahpepijat pada bila-bila masa semasa penyusunan.

Makro pratakrif

ANSI C mentakrifkan banyak makro. Anda boleh menggunakan makro ini dalam pengaturcaraan, tetapi anda tidak mengubah suai makro pratakrif ini secara langsung.

描述
__DATE__当前日期,一个以 "MMM DD YYYY" 格式表示的字符常量。
__TIME__当前时间,一个以 "HH:MM:SS" 格式表示的字符常量。
__FILE__这会包含当前文件名,一个字符串常量。
__LINE__这会包含当前行号,一个十进制常量。
__STDC__当编译器以 ANSI 标准编译时,则定义为 1。

Mari cuba contoh berikut:

#include <stdio.h>main(){
   printf("File :%s\n", __FILE__ );
   printf("Date :%s\n", __DATE__ );
   printf("Time :%s\n", __TIME__ );
   printf("Line :%d\n", __LINE__ );
   printf("ANSI :%d\n", __STDC__ );}

Apabila kod di atas (dalam fail test.c) disusun dan dilaksanakan, ia menghasilkan keputusan berikut:

File :test.cDate :Jun 2 2012Time :03:36:24Line :8ANSI :1

Pengendali prapemproses

Prapemproses C menyediakan pengendali berikut untuk membantu anda mencipta makro:

Pengendali kesinambungan makro ()

Makro biasanya ditulis pada satu baris. Tetapi jika makro terlalu panjang untuk dimuatkan pada satu baris, gunakan pengendali kesinambungan makro (). Contohnya:

#define  message_for(a, b)  \
    printf(#a " and " #b ": We love you!\n")
Pengendali pemalar rentetan (#)

Dalam takrifan makro, apabila anda perlu menukar parameter makro kepada pemalar rentetan, gunakan simbol operasi pemalar rentetan(# ). Operator yang digunakan dalam makro ini mempunyai argumen atau senarai argumen tertentu. Contohnya:

#include <stdio.h>#define  message_for(a, b)  \
    printf(#a " and " #b ": We love you!\n")int main(void){
   message_for(Carole, Debra);   return 0;}

Apabila kod di atas disusun dan dilaksanakan, ia akan menghasilkan keputusan berikut:

Carole and Debra: We love you!
Tandai operator tampal (##)

di dalam makro definisi Operator tampal token (##) menggabungkan dua argumen. Ia membenarkan dua teg bebas digabungkan menjadi satu teg dalam definisi makro. Contohnya:

#include <stdio.h>#define tokenpaster(n) printf ("token" #n " = %d", token##n)int main(void){   int token34 = 40;
   
   tokenpaster(34);   return 0;}

Apabila kod di atas disusun dan dilaksanakan, ia menghasilkan hasil berikut:

token34 = 40

Bagaimana ini berlaku adalah kerana kejadian ini menghasilkan output sebenar berikut daripada pengkompil :

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

Contoh ini menunjukkan bahawa token##n akan disambungkan kepada token34 Di sini, kami menggunakan pengendali pemalar rentetan (#) dan untuk menandakan simbol operasi tampal (##) . Operator

defined()

prapemproses defined operator digunakan dalam ungkapan malar untuk menentukan sama ada pengecam telah ditakrifkan menggunakan #define Pass. Nilai adalah benar (bukan sifar) jika pengecam yang ditentukan ditakrifkan. Jika pengecam yang ditentukan tidak ditentukan, nilainya adalah palsu (sifar). Contoh berikut menunjukkan penggunaan pengendali yang ditakrifkan():

#include <stdio.h>#if !defined (MESSAGE)   #define MESSAGE "You wish!"#endifint main(void){
   printf("Here is the message: %s\n", MESSAGE);  
   return 0;}

Apabila kod di atas disusun dan dilaksanakan, ia menghasilkan keputusan berikut:

Here is the message: You wish!

Makro Berparameter

Ciri CPP yang berkuasa ialah keupayaan untuk menggunakan makro berparameter untuk mensimulasikan fungsi. Sebagai contoh, kod berikut mengira kuasa dua nombor:

int square(int x) {   return x * x;}

Kita boleh menulis semula kod di atas menggunakan makro, seperti berikut:

#define square(x) ((x) * (x))

Sebelum menggunakan makro dengan parameter, anda mesti menggunakan #define takrif arahan. Senarai parameter disertakan dalam kurungan dan mesti segera mengikut nama makro. Tiada ruang dibenarkan antara nama makro dan kurungan pembukaan. Contohnya:

#include <stdio.h>#define MAX(x,y) ((x) > (y) ? (x) : (y))int main(void){
   printf("Max between 20 and 10 is %d\n", MAX(10, 20));  
   return 0;}

Apabila kod di atas disusun dan dilaksanakan, ia menghasilkan keputusan berikut:

Max between 20 and 10 is 20