zoukankan      html  css  js  c++  java
  • 预处理

    如:#include<stdio.h>,宏定义命令#define PI 3.14 等。

    在源程序中这些命令都放在函数之外,而且一般都放在源文件的前面,它们称为预处理部分。

    1、无参宏定义

    无参宏的宏名后不带参数。

    其定义的一般形式为:#define 标识符 字符串

    其中“#”表示这是一条预处理命令。

    define为宏定义命令。“标识符“为所定义的宏名。”字符串“可以是常数,表达式,格式串等。

    例:#define PI 3.14

    它的作用是指定标识符PI来代替数3.14。

    在编写源程序时,所有的3.14都可以用PI来代替,而对源程序做编译时,将先有预处理程序做宏代换,即用3.14表达式去置换所有的宏名PI,然后再进行编译。

    例:

    #include<stdio.h>
    #include "StdAfx.h"
    #define PI 3.14
    void main()
    {
        double s;
        int r;
        scanf("%d",&r);
        s=r*r*PI;
        printf("%g
    ",s);
    }

    说明:(1)宏命令是在一种简单的代换,字符串中可以是任何字符,常量或表达。预处理程序不会做任何检查,若有错误,只能在编译已被宏展开的源程序时发现。

    (2)宏命令不是说明或语句,不必加分号,若加分号,则连分号也一并置换。

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

    (4)宏名在源程序中若用引号括起,则预处理程序不对其作宏代换。

    例:

    #include<stdio.h>
    #include "StdAfx.h"
    #define PI 3.14
    void main()
    {
        void fun(void);
        double s;
        int r;
        scanf("%d",&r);
        s=r*r*PI;
        printf("%g
    ",s);
        fun();
    }
    void fun(void)
    {
        printf("PI=%g
    ",PI);
        printf("PI
    
    ");
    }

    (5)宏定义允许嵌套,在宏定义的字符串中可以使用已定义的宏名。在宏展开时有预处理程序层层代换。

    (6)习惯上宏名用大写字母表示,以便于与变量区别,但也允许小写字母。

    (7)可用宏定义表示数据类型,使书写方便。

    例:#define INTEGER int 

    注:宏定义表示数据类型和typedef定义数据说明符的区别:宏定义是简单的字符串代换,是在预处理完成的,它不是简单的代换,而是对类型说明符重命名。被命令的标识符具有类型定义说明的功能。

    例:

    #include<stdio.h>
    #include "StdAfx.h"
    #define PIN1 char*
    typedef char*PIN2;
    void main()
    {
        PIN1 x,y;
        PIN2 a,b;
        printf("#define:%d %d
    
    ",sizeof(x).sizeof(y));
        printf("typedef:%d %d
    
    ",sizeof(a),sizeof(b));
    }

    (8)对“输出格式”做宏定义,可以减少书写的麻烦。

    例:

    #include<stdio.h>
    #include "StdAfx.h"
    #define P printf
    #define D "%d
    "
    #define F "%f
    "
    void main()
    {
        int a=5,c=8,e=11;
        float b=3.8,d=9.1,f=21.08;
        P(D F,a,b);
        P(D F,c,d);
        P(D F,e,f);
    
    }

    2、带参宏定义

    C中允许宏带有参数,在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数。

    对带参数的宏,在调用中,不仅要宏展开,而且要用实参去代换形参。

    定义的一般形式为:#define 宏名(形参表)字符串

    调用的一般形式为:宏名(实参表);

    例:#define M(y) y*y+3*y     /*宏定义*/

      ……

      K=M(5)         /*宏调用*/

      ……

    在宏调用时,用实参5去代替形参y,经预处理宏展开后的语句为:k=5*5*+3*5;

    例:

    #include<stdio.h>
    #include "StdAfx.h"
    #define MAX(a,b) (a>b)?a:b
    void main()
    {
        int x,y,max;
        scanf("%d%d",&x,&y);
        max=MAX(x,y);
        printf("The max is %d
    ",max);
    }

    注:(1)在带参宏定义中,宏名和形参表之间不能有空格出现。

    (2)在带参宏定义中,形参不分配内存单元,因此不必做类型定义,而宏调用中的实参有具体的值,要用他们去代换形参,因此必须要做类型说明。刺出与函数不同,函数调用时进行的是“值传递”,而在带宏参数中,只是符号代换,不存在值传递问题。

    (3)在宏定义中形参是标识符,在宏调用中实参是表达式。

    例:

    #include<stdio.h>
    #include "StdAfx.h"
    #define SAY(y) (y)^(y)
    void main()
    {
        int i=0;
        char say[]={73,72,58,65,101,100,45,100,78};
        while(say[i])
        {
            say[i]=SAY(say[i])^say[i];
            i++;
        }
        printf("%s
    ",say);
    }

    (4)在宏定义中,字符串内的形参通常用括号括起来以避免出错。

    例:

    #include<stdio.h>
    #include "StdAfx.h"
    #define SQ(y) (y)*(y)
    void main()
    {
        int a,sq;
        printf("input a number:");
        scanf("%d",&a);
        sq=160/SQ(a+1);
        printf("sq=%d
    ",sq);
    }

    (5)带参宏与带参函数很相似,但本质上是不同的,同一表达式的处理与用宏处理两者的结果有可能是不同的。

    (6)宏定义也可用来定义多个语句,在宏调用时又把这些语句代换到程序内。

    例:

    #include "StdAfx.h"
    #include<stdio.h>
    #include<string.h>
    
    #define STR(s1,s2,s3,sum) strcat(strcat(strcat(sum,s1),s2),s3);
    void main()
    {
        char str1[]="I",str2[]="love",str3[]="China",str[40]="";
        STR(str1,str2,str3,str);
        printf("
    	str1=%s
    	str2=%s
    	str3=%s
    	str=%s
    ",str1,str2,str3,str);
    }
  • 相关阅读:
    小记面向对象
    公司分层思想的演化历程
    我对uml类图关系的理解
    cms真实问题的来源以及模拟解决方案
    HTTP 协议基础
    Requests库
    接口测试概念
    Python中的strip()函数的用法
    Robot Framework环境搭建
    Python unittest excel数据驱动
  • 原文地址:https://www.cnblogs.com/lvfengkun/p/10371574.html
Copyright © 2011-2022 走看看