zoukankan      html  css  js  c++  java
  • #define的使用方法体会

    #define 创建一个宏,该宏是标识符或參数化标识符与标记字符串的关联。

     在定义宏之后。编译器可用标记字符串替换源文件里标识符的每一个匹配项。

    语法

    #define identifier token-string 

    #define identifier ( identifier 1 , ... , identifier n ) token-string 

    备注

    1 #define 指令促使编译器用 token-string 替换源文件里 identifier 的每一个匹配项。 仅当 identifier 构成标记时才替换它。 也就是说,假设 identifier 出如今凝视、字符串或较长的标识符中。则不会替换它。

    2 另外一种形式类似于函数,比如

    #define mul(a,b) (a*b) 形參名称将出如今 token-string 中以标记实际值的替换位置。

    token-string 中前面未带stringizing (#)、charizing(#@) 或 token-pasting (##) 运算符或后面未跟 ## 运算符的每一个形參将由相应的实參替换。

     

    注意:

    1 宏就是简单的字符替换,注意替换后的运算符优先级可能会影响宏定义所要表达的。所以要善于使用小括号。比如:

    #define Add(a,b) a+b  假设使用的时候:2*Add(1,2) 原本想让它等于6,但替换后变成2*1+2=4。

    所以要注意。

    2 #define中的换行符是反斜杠

    假设一行没写完。直接加一个,下一行继续写就能够了。

    3 注意这里仅仅是字符替换。宏定义中不应含有return等语句。想一想替换后。会变成什么样子。

     

    宏的返回值的两种形式:

    1 操作符。

    #define Max(a,b) (((a)>(b))(a):(b))

    #define add(a,b) ((a)+(b))

    2 将返回值赋值给一个额外的形參。这个形參就是返回值。

    #define cal(a,b,c) {c=a+b;}

     

    一个很有意思的样例:

    定义一个求最大值的宏。

    可能会这么写:#define Max(a,b) ((a)>(b) ?

    a):(b))

    这么做可能对于大多数情况是没有错误的,可是事实上这么做是不严谨的。比如:

    #define Max(a,b) ((a)>(b)? (a):(b))

    int fun(int *a)

    {

      *a=*a+1;

       return *a;

    }

    main()

    {

    int a=1,b=2,c;

    c=Max(a,fun(&b));

    }//我们想得到的c的值应该是3,但实际会发现c的值是4.

    由于首先我们替换:c=((a)>(fun(&b))?

    (a):(fun(&b)));

    能够发现fun运行了两次。b的值加了两次变成了4.所以结果是4.

     

    这里给出一个严谨的做法:

    使得參数仅仅被运行一次。

    #define Max(a,b) ({

       typeof(a) _a=(a);

       typeof(b) _b=(b);

       (_a>_b)? _x : _y; })

    这样就不会有上述的问题了。

    注意:({...})的作用是将内部的几条语句中最后一条的值返回,它也同意在内部声明变量(由于它通过大括号组成了一个局部Scope)。用此能够达到return的目的。

    !!

    注:这里使用了typeof。它是c的一个新扩展。而在vs200520102013中都无法使用。

    仅仅能在在线编译器下运行。结果是对的。

    观察发现:vs中不识别keywordtypeof了。在C++中可用decltype实现相似功能,求某个变量的类型。并且vs中也不能够有这种({...})的东西了。

    要么#define.. () 要么#define .. {}

    所以上面的做法能够改成:

    #define MIN(X,Y,M) {

           decltype(X)x_ = (X);

           decltype(Y)y_ = (Y);

           M=(x_ < y_) ? x_ : y_; }

    使用时:int a=1,b=2,c; Max(a,b,c);c为返回值。不參与运算。

     

     

    #与##与#@在#define中的使用方法:

     

    #的意思是不展开參数

    假设在token-string  中出现以#开头。意思是:不展开參数。直接替换。

    假设在token-string  中出现不以#开头,意思是:展开參数。直接替换。

    比如:

    #define f(a) a+1

    #define T(a) #a

    #define H(a) a

    T(f(a))->f(a)->a+1

    H(f(a))->H(a+1)->a+1

    尽管结果一样,可是过程不一样。

     

    ##的意思是字符串连接符

    比如:

    #define f(a,b) a##b##lobe

    结果就是ablobe

    注意:##不能出如今开头,也不能出如今结尾。仅仅能出如今中间。

     

    #@字符化运算符

    Microsoft 专用

    charizing 运算符仅仅能与宏的參数一起使用。 假设宏的定义中的形參前有 #@。则会在扩展宏时用单引號括起实參并将其视为一个字符。

    #define makechar(x)  #@x

    ==

    char a= makechar(x);

    比如:

    #define H(x) #@x

    cout<<H(a)<<endl;

    输出结果:a

    cout<<H(ab)<<endl;

    输出结果:24930

    注解:就是相当于把#@后面的实參变成一个字符型的字符。

  • 相关阅读:
    C++ Programming with TDD之一:GMOCK框架简介
    Linux Programming之MySQL
    Python之自动单元测试之一(unittest使用实例)
    关于过去的这一个月——面试经历
    谈谈Python中对象拷贝
    C++之Effective STL学习笔记Item21
    C++之Effective STL学习笔记Item7
    C++之Effective STL学习笔记Item20
    C++之Effective STL学习笔记Item14
    Coding Rules
  • 原文地址:https://www.cnblogs.com/tlnshuju/p/6877818.html
Copyright © 2011-2022 走看看