• 【C进阶】之宏定义的扩展


    1. 常量宏定义

    使用c中的#define 来定义一个常量来表示一年有多少秒

    #define SECONDS_PER_YEAR (606024*365)UL

    求圆的周长:

    #define D® (r + r) //使用D(5) * 3.14 -----> (5 + 5) * 3.14

    2. 定义宏函数

    在定义宏函数时,最后一个表达式的结果就是宏函数的返回值

    格式:

    ​ #define 宏函数名(形参表) ({语句1;语句2;语句3…})

    ​ 形参没有数据类型,只有参数名

    请写一个“标准”的宏MIN,这个宏输入两个参数并返回较大较小值
    #include 
    
    #define MIN(A,B)  ({A<B?A:B;})
    //宏定义分成多行书写,行尾必须加续行符 
    #define MAX(A,B)  ({int ret;\
                            if(A<B)\
                                ret=B;\
                            else    \
                                ret=A;\
                            ret;})
    
    int main(int argc, char const *argv[])
    {
        int min=MIN(100,200);
        printf("min value=%d\n",min);
        int max=MAX(100,200);
        printf("max value=%d\n",max);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    3. 宏定义和#号结合

    #可以将宏的参数转换为一个字符串

    #include 
    #define NAME "lisi"
    #define NAME1(n)  n
    #define NAME2(n)  #n
    int main(int argc, char const *argv[])
    {
    
    	printf("%s\n",NAME);   //------>printf("%s\n","lisi");
    	
    	printf("%s\n",NAME1(lisi));   //------>printf("%s\n",lisi); //error
    	
    	printf("%s\n",NAME2(lisi));   //------>printf("%s\n","lisi"); //error
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    预处理之后的效果:

    # 5 "test02.c"
    int main(int argc, char const *argv[])
    {
    
     printf("%s\n","lisi");
    
     printf("%s\n",lisi);
    
     printf("%s\n","lisi");
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    4. 宏定义和两个#结合

    两个#可以实现字符串的拼接

    // 将a和b代表的字符串拼接生成一个新的字符串
    #define  type(a, b)     a##b
    
    type(uint, _t)  ----> 预处理阶段展开之后的结果 : uint_t
    
    • 1
    • 2
    • 3
    • 4

    练习:int型、short型、char型的数据比较大小

    #include 
    
    #if 0
    int max_int(int a,int b){
        return a>b?a:b;
    }
    short max_int(short a,short b){
        return a>b?a:b;
    }
    char max_int(char a,char b){
        return a>b?a:b;
    }
    #endif
    //使用宏定义完成函数模板
    #define MAX(T) T max_##T (T a,T b){return a>b?a:b;}
    
    //使用宏定义,定义max_int max_short max_char函数
    MAX(int)
    MAX(short)
    MAX(char)
    #define max_value(T) max_##T
    int main(int argc, char const *argv[])
    {
        // printf("int max value =%d \n",max_int(10000,300000));
        // printf("short max value =%d \n",max_short(100,300));
        // printf("char max value =%c \n",max_char('a','b'));
    
        printf("int max value =%d \n",max_value(int)(10000,300000));
        printf("short max value =%d \n",max_value(short)(100,300));
        printf("char max value =%c \n",max_value(char)('a','b'));
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    预处理代码:

    int max_int (int a,int b){return a>b?a:b;}
    short max_short (short a,short b){return a>b?a:b;}
    char max_char (char a,char b){return a>b?a:b;}
    
    int main(int argc, char const *argv[])
    {
    
    
    
    
        printf("int max value =%d \n",max_int(10000,300000));
        printf("short max value =%d \n",max_short(100,300));
        printf("char max value =%c \n",max_char('a','b'));
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    5. 宏定义和do…while()的结合

    使用场合:如果在宏定义阶段,有多条语句,最后将c语句用do…while()包裹起来

    #include 
    #include 
    #include 
    
    #define PRINT() printf("%s:%s:%d\n",__FILE__,__func__,__LINE__);\
                  printf("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    
    #define DBUG() do{printf("%s:%s:%d\n",__FILE__,__func__,__LINE__);\
                  printf("%s:%s:%d\n",__FILE__,__func__,__LINE__);}while(0)
    int main(int argc, const char *argv[])
    {
        int a=100,b=200;
    #if 0
        /*
            调试宏:
            __FILE__:文件名
            __func__:函数名
            __LINE__:当前行号
        */
        // if(a>b){
        //     printf("%s:%s:%d\n",__FILE__,__func__,__LINE__);
        //     printf("%s:%s:%d\n",__FILE__,__func__,__LINE__);
        // }else{
        //     printf("%s:%s:%d\n",__FILE__,__func__,__LINE__);
        //     printf("%s:%s:%d\n",__FILE__,__func__,__LINE__);
        // }
    
        if(a>b){
            PRINT()
        }else{
            PRINT()
        }
    #endif
    #if 0
        //如果if或者else只有一条语句,可以省略{}
        //包括while,for循环语句都一样
        if(a>b)
            PRINT()
        else
            PRINT()
        // if和else宏替换后,变成两句,替换后语法错误,解决办法就是使用宏定义和do....while结合
    #endif
        // if和else宏替换后,变成两句,替换后语法错误,解决办法就是使用宏定义和do....while结合
        if(a>b)
            DBUG();
        else
            DBUG();
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    6. #ifdef…#else…#endif

    格式:

    #define 宏定义的名字

    #ifdef 宏定义的名字

    ​ //如果宏定义被定义了,这段代码有效

    #else

    ​ //如果宏定义没被定义,这段代码有效

    #endif

    7. #ifndef…#else…#endif

    格式:

    #define 宏定义的名字

    #ifndef 宏定义的名字

    ​ //如果宏定义没被定义了,这段代码有效

    #else

    ​ //如果宏定义被定义,这段代码有效

    #endif

    8. #if defined() … #else … #endif ----> 底层代码使用较多

    格式:
    #if defined(宏定义的名字)
    	// 如果宏定义被定义了,则这段代码有效
    #else
    	// 如果宏定义没有被定义,则这段代码有效
    #endif 
    
    #if !defined(宏定义的名字)
    	// 如果宏定义没有被定义,则这段代码有效
    #else
    	// 如果宏定义被定义了,则这段代码有效
    #endif 
    
    // #if defined可以进行逻辑运算
    
    #if defined(宏定义的名字1) || defined(宏定义的名字2)
    	// 以上两个宏定义只要有一个定义了,则这段代码有效
    #else
    	// 以上两个宏定义都没有定义,则这段代码有效
    #endif 
    
    #if defined(宏定义的名字1) && defined(宏定义的名字2)
    	// 以上两个宏定义都被定义了,则这段代码有效
    #else
    	// 以上两个宏定义只要有一个没有定义,则这段代码有效
    #endif 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

  • 相关阅读:
    linux开发技术栈
    学习ASP.NET Core Blazor编程系列十四——修改
    Java设计模式之状态模式
    SQL中的CASE WHEN语句:从基础到高级应用指南
    apache 漏洞
    HiveServer2 常见异常和处理方法
    smt加工企业多不多?如何进行了解?
    使用GPT训练中秋古诗写作讲解
    零经验,小白变大厨!
    准备pmp考试第10天
  • 原文地址:https://blog.csdn.net/distant_Rove666/article/details/127545536