c语言学习之基础知识点介绍(二十):预处理指令

时间:2021-07-26 17:13:34

一、预处理指令的介绍

预处理命令:在编译之前触发的一系列操作(命令)就叫预处理命令。
特点:以#开头,不要加分号。

#include:
  文件包含指令
  把指定文件的内容复制到相应的位置

#define:
  #define 宏名 替换的值;
  宏、宏定义或者还叫宏代换。
  作用:就是在编译之前把所有用到这个宏的地方,替换成你指定的东西
  规范:宏名大写,可以跟变量区分开来

之前学的宏:
  INT32_MAX
  INT32_MIN

宏不占据内存空间,只是帮你做简单的替换。

注意:

1.宏只是简单的替换,不参与编译,宏不会编译成指令集。
2.宏可以写在任意位置,但是一定要调用它之前。
3.宏可以嵌套,展开的时候依次展开。
4.宏只是简单的替换,如果替换的内容是表达式,它不会帮你先计算出结果,而是把整个表达式替换过去。
5.宏替换的作用域:默认是从声明的位置到文件的结束,可以用#undef 宏名 结束宏的作用。
6.双引号里面如果有遇到宏名,不会做替换,如果单引号里面写的是宏名也不会替换。

代码实例:

#include <stdio.h>

#define SUM 10 + NUM

#define NUM 10

#define MY_TEST int num = 30;

#define GET_SUM 10+30

#define HAHA GET_SUM*2

#define A 'a'

int main(int argc, const char * argv[]) {

    printf("%d\n",TEST_NUM);

//    char ch = 'A';
//
// printf("%c\n",ch);//A // printf("NUM \n");//NUM #undef NUM /*
printf("%d\n",NUM);//编译的时候,把这句话换成了printf("%d\n",10); int num = NUM + 30; //替换成了 int num = 10 + 30; printf("num=%d\n",num);
*/ //int num = INT32_MAX; //编译的时候把它替换成了 int num = 2147483647; // int num = SUM;
//
// printf("num=%d\n",num); // MY_TEST
// printf("%d\n",num); // printf("%d\n",GET_SUM);//40 // int res = GET_SUM * 2; // int res = 10+30*2;
// printf("%d\n",res);//
// printf("%d\n",HAHA);//先替换成(GET_SUM)*2 然后再替换成 (10+30)*2
return ;
}

二、预处理之#if-#elif -#else

/*
用的比较少
#if 宏的表达式 #elif 宏的表达式2 #else #endif 有选择的编译或者不编译某些代码 注意:#if这只能跟宏
一定要以#endif结尾 */ #include <stdio.h>
#define SCORE 65 int main(int argc, const char * argv[]) {
//以下永远只有一条语句参与编译
#if SCORE >= 90
printf("法拉利\n");
#elif SCORE >= 80
printf("奔驰\n");
#elif SCORE >= 70
printf("大众\n");
#elif SCORE >= 60
printf("拖拉机\n");
#else
printf("吊打\n");
#endif
return ;
}

三、预处理之#ifdefine

/*

 #ifdef:
#ifdef 宏名
代码段;
#endif 语义:如果定义了宏名,那么就编译代码段,否则不编译 #ifndef:
#ifndef 宏名
代码段;
#endif 语义:如果没有定义这个宏,那么就编译代码段,否则不编译 作用:1.防止重复导入 */ #include <stdio.h> #include "test.h" //#define TEST int main(int argc, const char * argv[]) { /*
#ifdef TEST printf("哈哈哈哈哈,我被定义了\n");
#endif
*/ #ifndef TEST printf("哈哈哈哈哈,我被定义了\n");
#endif return ;
}

四、有参数的宏

/*

    #define 宏名  替换的值

    有参数的宏:
#define 宏名(参数列表) 参数1+参数2
*/ #include <stdio.h> #define MY_NUM(a) a #define MY_SUM(a) a*2 #define MY_SUM2(a,b) a*b int main(int argc, const char * argv[]) { /*
int num = MY_NUM(30); printf("num=%d\n",num); int num2 = MY_SUM(20); printf("num2=%d\n",num2);//40 printf("%d\n",MY_NUM(50));//50 printf("%d\n",MY_SUM(50));//100 int num3 = MY_SUM2(10, 20); printf("num3=%d\n",num3);
*/ char ch2 = 'z'; char ch = MY_NUM(ch2); printf("%c\n",ch);//z return ;
}

五、条件编译的用处

/*

 条件编译:
就是有选择的编译或者不编译某段代码 #if-#elif-#else-#endif #ifdef-#endif #ifndef-#endif 用来开发时的测试调试,能够改一个值就可以让这些输出的语句消失(不参与编译),就可以达到一次性把所有调试语句“删除”的目录 */ #include <stdio.h> //#define MY_DEBUG #ifndef MY_DEBUG #define LOG(a,...) #else #define LOG(a,...) printf(a, ##__VA_ARGS__); //就代表第二个参数是可变的,你可以传,也可以不传,传的话也可以传一个或者多个 #endif
int main(int argc, const char * argv[]) {
LOG("哈哈哈哈,测试1,a=%d b=%d\n",a,b);//第二个参数,只传了2个
LOG("哈哈哈,测试2\n"); //第二个参数,一个都没传 LOG("z=%d,x=%d,q=%d,v=%d\n",z,x,q,v);//第二个参数,传了4个
return ;
}