zoukankan      html  css  js  c++  java
  • C语言宏定义、条件编译

    笔记整理:

    C语言带参数宏定义

    宏定义

    宏定义的一般形式为:
    #define 宏名 字符串或者表达式
    预处理的工作就是替换,就是将宏名替换成相应的字符串与表达式。

    宏定义字符串:

    #define 宏名 字符串

    该示例中的语句int sum = 20 + N;,N被100代替了

    #include <stdio.h>
    #define N 100
    int main(){
        int sum = 20 + N;
        printf("%d
    ", sum);
        return 0;
    }

    宏定义表达式:

    #define  宏名  (表达式)
    #include <stdio.h>
    #define M (n*n+3*n)
    int main(){
        int sum, n;
        printf("Input a number: ");
        scanf("%d", &n);
        sum = 3*M+4*M+5*M;
        printf("sum=%d
    ", sum);
        return 0;
    }

    注意:宏定义中表达式必须用括号

    对宏定义的几点说明

    1) 宏定义是用宏名来表示一个字符串,在宏展开时又以该字符串取代宏名,这只是一种简单粗暴的替换。字符串中可以含任何字符,它可以是常数、表达式、if 语句、函数等,预处理程序对它不作任何检查,如有错误,只能在编译已被宏展开后的源程序时发现。

    2) 宏定义不是说明或语句,在行末不必加分号,如加上分号则连分号也一起替换。

    3) 宏定义必须写在函数之外,其作用域为宏定义命令起到源程序结束。如要终止其作用域可使用#undef命令。例如:
    表示 PI 只在 main() 函数中有效,在 func() 中无效。

    #define PI 3.14159
    int main(){
        // Code
        return 0;
    }
    #undef PI
    void func(){
        // Code
    }

    4)代码中的宏名如果被引号包围,那么预处理程序不对其作宏代替。

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

    #define PI 3.1415926
    #define S PI*y*y    /* PI是已定义的宏名*/
    对语句:
    printf("%f", S);
    在宏代换后变为:
    printf("%f", 3.1415926*y*y);

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

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

    #define UINT unsigned int

    在程序中可用 UINT 作变量说明:

    UINT a, b;

    应注意用宏定义表示数据类型和用 typedef 定义数据说明符的区别。宏定义只是简单的字符串替换,由预处理器来处理;而 typedef 是在编译阶段由编译器处理的,它并不是简单的字符串替换,而给原有的数据类型起一个新的名字,将它作为一种新的数据类型。


    带有参数的宏定义


    C语言允许宏带有参数。在宏定义中的参数称为“形式参数”,在宏调用中的参数称为“实际参数”,这点和函数有些类似。

    对带参数的宏,在展开过程中不仅要进行字符串替换,还要用实参去替换形参。

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

    在字符串中可以含有各个形参,形参列表中参数以逗号分隔。

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

    #define M(y) y*y+3*y //宏定义
    // Code
    k=M(5); //宏调用
    
     

    注意:

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

    结果:

    input a number: 9
    sq=100

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

    结果:

    input a number: 9
    sq=19

    条件编译

    ⑴        #if…#else…格式

    #if 判断条件
               代码段1
    #else
               代码段2
    #endif
    或者
    
    #if 判断条件1
               代码段1
    #elif 判断条件2
               代码段2
    #else
               代码段3
    #endif

    功能:和if…else…表达式是一样的。适用的场景是存在真假的判断条件,此条件一般情况下是一个表达式。


    ⑵        #ifdef…#else…或者#ifndef…#else…格式

    #ifdef 标识符
               代码段1
    #else
               代码段2
    #endif
    
    或者
    
    #ifndef 标识符
               代码段1
    #else
               代码段2
    #endif

    功能:判断条件主要是查看标识符是否被定义(#define定义)。

    在现实的工程项目中会使用大量的条件编译。比如说通过条件编译来使用各个不同的硬件平台;通过条件编译来实现平台和产品线管理;通过条件编译来区分正式版本和调试版本等等。

    部分预处理指令

    指令 说明
    # 空指令,无任何效果
    #include 包含一个源代码文件
    #define 定义宏
    #undef 取消已定义的宏
    #if 如果给定条件为真,则编译下面代码
    #ifdef 如果宏已经定义,则编译下面代码
    #ifndef 如果宏没有定义,则编译下面代码
    #elif 如果前面的#if给定条件不为真,当前条件为真,则编译下面代码
    #endif 结束一个#if……#else条件编译块

  • 相关阅读:
    根据字符串拆分字符串
    .NET WinForm读取扫描枪从COM口传过来的数据,显示在TextBox中,并做其他操作。
    《将博客搬至CSDN》
    mysql学习(二)DML
    mysql学习(一)DDL
    BigDecimal
    排序
    2017
    oracle的mapper小结
    数据结构查找
  • 原文地址:https://www.cnblogs.com/-wenli/p/12459416.html
Copyright © 2011-2022 走看看