C语言_预处理

宏定义

宏: 在C语言源程序中允许用一个标识符(宏名)来表示一个字符串(常数、表达式、格式串)
define 宏定义命令
宏定义是由源程序中宏定义命令完成的

宏代换(宏扩展): 在编译预处理时,对程序中所有出现的宏名,都用宏定义中的字符串去代换
# 预处理命令
宏代换是由预处理程序自动完成的

无参宏定义

#define 标识符 字符串

计算: 3 ∗ ( y 2 + 3 y ) + 4 ( y 2 + 3 y ) + 5 ( y 2 + 3 y ) 3*(y^2 + 3y)+4(y^2 + 3y)+5(y^2 + 3y) 3(y2+3y)+4(y2+3y)+5(y2+3y)

#include<stdio.h>
#define M (y*y + 3*y)

int main(){
	int s,y;
	printf("input a number: \n");
	scanf("%d",&y);
	s = 3*M + 4*M + 5*M;
	printf("s=%d \n", s);
}

在这里插入图片描述

  1. 宏名在源程序中若引号""括起来,则预处理程序不对其作宏代换
#include<stdio.h>
#define OK 100

int main(){
	printf("OK \n");
}

在这里插入图片描述

  1. 宏定义允许嵌套
#include<stdio.h>
#define PI 3.1415926
#define S PI*y*y

int main(){
	int y;
    printf("please input a number: \n");
    scanf("%d",&y);
    printf("\n");
    printf("PI=%f \n",PI);
    printf("S=%f \n",S);
}

在这里插入图片描述

  1. 习惯上宏名用大写字母表示,以便与变量区别. 但允许使用小写字母

  2. 宏定义表示数据类型,使书写方便

  3. 对"输出格式"作宏定义,可以减少书写麻烦

#include<stdio.h>

#define P printf
#define D "%d\n"
#define F "%f\n"

int main(){
    int a=5, c=8, e=11;
    float b=3.8, d=9.7, f=21.08;
    P(D F, a,b);
    P(D F, c,d);
    P(D F, e,f);
}

在这里插入图片描述

undef 终止其作用域

宏定义必须写在函数之外,其作用域为宏定义命令起止源程序结束,如要终止其作用域可使用 undef 命令

#include<stdio.h>
#define PI
#define NEW (PI*3)
#undef PI
#define PI 100

int main(){
	printf("NEW: %d \n",NEW);
	printf("PI: %d \n",PI);
}

在这里插入图片描述

带参宏定义

#define 宏名(形参表) 字符串
在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数.

#include<stdio.h>
#define MAX(a,b) (a>b)?a:b

int main(){
    int x,y,max;
    printf("input two numbers: \n");
    scanf("%d%d",&x,&y);
    max=MAX(x,y);
    printf("max=%d \n",max);
}

在这里插入图片描述

  1. 带参宏定义中,宏名和形参表之间不能有空格出现
  2. 在宏定义中,形参参数不分配内存单元,因此不必作类型定义.而宏调用中的实参有具体的值.要用它们去代替形参,因此必须作类型说明.
    与函数中形参实参区别:
    在函数中,形参和实参是两个不同的量,各有自己的作用域,调用时要把实参值赋予形参,进行"值传递"
    在带参宏中,只是符号代换,不存在值传递问题
    3.在宏定义中的形参是标识符,而宏调用中的实参可以是表达式
#include<stdio.h>
#define SQ(y) (y)*(y)

int main(){
    int a,sq;
    printf("input a number: \n");
    scanf("%d",&a);
    sq=SQ(a+1);
    printf("sq=%d\n",sq);
}

在这里插入图片描述

  1. 在宏定义中,字符串内的形参通常要用括号扩起来以避免出错
    #define SQ(y) (y)*(y) 正确 ( y ) ∗ ( y ) = ( a + 1 ) ∗ ( a + 1 ) = 4 ∗ 4 = 16 (y)*(y)=(a+1)*(a+1)=4*4=16 (y)(y)=(a+1)(a+1)=44=16 否则 #define SQ(y) y*y 与目标相悖 y ∗ y = a + 1 ∗ a + 1 = 3 + 1 ∗ 3 + 1 = 7 y*y=a+1*a+1=3+1*3+1=7 yy=a+1a+1=3+13+1=7
  2. 带参的宏和带参的函数很相似,但有本质不同.
    把同一表达式用函数处理与用宏处理两者的结果有可能是不同的
#include<stdio.h>

int S(int y){
    return ((y)*(y));
}

int main(){
    int i=1,answer;
    while(i<=5){
        answer = S(i++); 
        printf("%d\n",answer);
    }
}

在这里插入图片描述

#include<stdio.h>

#define SQ(y) ((y)*(y))

int main(){
    int i=1;
    while(i<=5){
        printf("%d\n",SQ(i++));
    }
}

在这里插入图片描述
SQ(i++) 被替换成 ((i++)*(i++))
第一循环 i=1 时, 第一个i++为1, 第二个i++ 为2
第二次循环, 即 i=3, 第一个i++为3, 第二个i++ 为4

  1. 宏定义也可以定义多个语句,在宏调用时,把这些语句又代换到源程序内
#include<stdio.h>

#define SSSV(s1,s2,s3,v) s1=l*w; s2=l*h; s3=w*h; v=w*l*h;

int main(){
    int l=3, w=4, h=5, sa,sb,sc,vv;
    SSSV(sa,sb,sc,vv);
    printf("sa=%d\nsb=%d\nsc=%d\nvv=%d\n",sa,sb,sc,vv);
}

在这里插入图片描述

文件包含

#include"文件名"
功能: 把指定的文件插入该命令行位置取代该命令行,从而把指定的文件和当前的源程序文件连接成一个源文件.
eg:
#include<stdio.h>
#include<math.h>

条件编译

可以按不同的条件去编译不同的程序部分,因而产生不同的目标代码文件

形式1

#ifdef 标识符
	程序段1
#else
	程序段2
#endif

标识符已被 #define 命令定义过则对程序段1进行编译;否则对程序段2进行编译.

如果没有程序段2(它为空),本格式中#else可以没有.

#include<stdio.h>
#include<stdlib.h>

#define NUM ok
int main(){
    struct stu{
        int num;
        char *name;
        char sex;
        float score;
    } *ps;
    ps = (struct stu*)malloc(sizeof(struct stu));
    ps -> num=102;
    ps -> name="Miko woo";
    ps -> sex='M';
    ps -> score=62.5;
    #ifdef NUM
        printf("Number=%d\nScore=%f\n", ps->num, ps-> score);
    #else
        printf("Name=%sSex=%c\n", ps->name, ps->sex);
    #endif
    free(ps);
}

在这里插入图片描述

形式2

#ifndef 标识符
	程序段 1
#else
	程序段 2
#endif

如果标识符#define 命令定义过则对程序段1进行编译; 否则对程序段2进行编译.

形式3

# if 常量表达式
	程序段 1
#else
	程序段 2
#endif

如常量表达式的值为真(非0),则对程序段1进行编译,否则对程序段2进行编译.

#include<stdio.h>

#define R 1
int main(){
    float c,r,s;
    printf("input a number:\n");
    scanf("%f",&c);
    #if R
        r = 3.14159*c*c;
        printf("area of round is :%f \n", r);
    #else
        s = c*c;
        printf("area of squre is :%f \n", s);
    #endif
}

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值