C语言基础——预处理


预处理

1.C语言在对源程序进行编译之前,会先对一些特殊的预处理指令作解释(比如之前使用的#include文件包含指令),产生一个新的源程序(这个过程称为编译预处理),之后再进行通常的编译
2.为了区分预处理指令和一般的C语句,所有预处理指令都以符号"#"开头,并且结尾不用分号
3.预处理指令可以出现在程序的任何位置,它的作用范围是从它出现的位置到文件尾。习惯上我们尽可能将预处理指令写在源程序开头,这种情况下,它的作用范围就是整个源程序文件
4.C语言提供的预处理指令主要有:宏定义、
条件编译、 件包含
4.预处理指令在代码翻译成0和1之前执行
5.预处理的位置是随便写的
6.预处理指令的作用域:从编写指令的那一行开始,一直到文件结尾,可以用#undef取消宏定义的作用
7.宏名一般用大写或者以k开头,变量名一般用小写



不带参数的宏定义


1.一般形式
#define 宏名 字符串
比如#define ABC 10
右边的字符串也可以省略,比如#define ABC

2.作用
它的作用是在编译预处理时,将源程序中所有"宏名"替换成右边的"字符串",常用来定义常量。

3.使用习惯与注意

1> 宏名一般用大写字母,以便与变量名区别开来,但用小写也没有语法错误
2> 对程序中用双引号扩起来的字符串内的字符,不进行宏的替换操作。
3> 在编译预处理用字符串替换宏名时,不作语法检查,只是简单的字符串替换。只有在编译的时候才对已经展开宏名的源程序进行语法检查
4> 宏名的有效范围是从定义位置到文件结束。如果需要终止宏定义的作用域,可以用#undef命令
5> 定义一个宏时可以引用已经定义的宏名

#include <stdio.h>


//#define kCount 4

int main()
{
    char *name = "COUNT";
    
    printf("%s\n", name);
    
    #define COUNT 4
    
    int ages[COUNT] = {1, 2, 67, 89};
    
    
    
    for ( int i = 0; i<COUNT; i++) {
        printf("%d\n", ages[i]);
    }
    
    // 从这行开始,COUNT这个宏就失效
#undef COUNT
    
    int a = COUNT;
    
    return 0;
}
 

带参数的宏定义

1.一般形式
#define 宏名(参数列表) 字符串

2.作用
在编译预处理时,将源程序中所有宏名替换成字符串,并且将 字符串中的参数 用 宏名右边参数列表 中的参数替换

3.使用注意
1> 宏名和参数列表之间不能有空格,否则空格后面的所有字符串都作为替换的字符串
2> 带参数的宏在展开时,只作简单的字符和参数的替换,不进行任何计算操作。所以在定义宏时,一般用一个小括号括住字符串的参数。



int sum(int a, int b)
{
    return a + b;
}*/
#include <stdio.h>

#define sum(v1, v2) ((v1)+(v2))

#define pingfang(a) ((a)*(a))

int main()
{
    // pingfang(5+5) (10*10)
    // pingfang(5+5)
    // pingfang(5+5) (35)
    // pingfang(5+5)/pingfang(2)
    int c = pingfang(5+5)/pingfang(2);
    
    printf("c is %d\n", c);
    /*
    int c = sum(2, 3) * sum(6, 4);
    
    printf("c is %d\n", c);*/
    /*
    int a = 10;
    
    int b = 20;
    
    
    int c = sum(a, b);
    
    printf("c is %d\n", c);
    //int c = sum(a, b);*/
    
    return 0;
}

 
与函数的区别

从整个使用过程可以发现,带参数的宏定义,在源程序中出现的形式与函数很像。但是两者是有本质区别的:
1> 宏定义不涉及存储空间的分配、参数类型匹配、参数传递、返回值问题
2> 函数调用在程序运行时执行,而宏替换只在编译预处理阶段进行。所以带参数的宏比函数具有更高的执行效率


条件编译

在很多情况下,我们希望程序的其中一部分代码只有在满足一定条件时才进行编译,否则不参与编译(只有参与编译的代码最终才能被执行),这就是条件编译。

基本用法

1 #if 条件1
2  ...code1...
3 #elif 条件2
4  ...code2...
5 #else
6  ...code3...
7 #endif

1> 如果条件1成立,那么编译器就会把#if 与 #elif之间的code1代码编译进去(注意:是编译进去,不是执行,很平时用的if-else是不一样的)
2> 如果条件1不成立、条件2成立,那么编译器就会把#elif 与 #else之间的code2代码编译进去


3> 如果条件1、2都不成立,那么编译器就会把#else 与 #endif之间的code3编译进去


4> 注意,条件编译结束后,要在最后面加一个#endif,不然后果很严重(自己思考一下后果)


5> #if 和 #elif后面的条件一般是判断宏定义而不是判断变量,因为条件编译是在编译之前做的判断,宏定义也是编译之前定义的,而变量是在运行时才产生的、才有使用的意义


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值