精华内容
下载资源
问答
  • C++宏定义函数

    万次阅读 2019-04-13 15:45:48
    这句几乎每个类都有,一开始以为是TypeName(“xxx”)调用构造函数,细看不太对,应该是调用宏定义函数,这个宏函数原型在$SRC/OpenFOAM/db/typeInfo文件里定义的。 如下: #define TypeName(TypeNameString) ...

    在看OpenFoam源码的时候突然看到TypeName(“xxx”);这句几乎每个类都有,一开始以为是TypeName(“xxx”)调用构造函数,细看不太对,应该是调用宏定义的函数,这个宏函数原型在$SRC/OpenFOAM/db/typeInfo文件里定义的。

    如下:

    #define TypeName(TypeNameString)       \
         ClassName(TypeNameString);          \
     virtual const word& type() const {return typeName;} 

    官方注释是:声明了ClassName()用一个纯虚类型的info

    ClassName()呢本身也是一个宏定义函数,看一下它的定义

    #define ClassName(TypeNameString)       \
     classNameNoDebug(TypeNameString);       \
     static int debug

    对于ClassName(),官方注释和解释是:add typeName information from argument TypeNameString to a class.

    also declares debug information

    首先理解宏定义到底是什么,最简单的当然是

    #define a 10
    #define b a

    宏定义是一种简单的语义替换。

    它在元编程时有两种风格,如下所示

    //第一种,这里identifier是宏的名字,replacement-list是零个或多个标记序列,
    //后继的程序文本中所有出现的identifier的地方都会被预处理器展开为相应的replacemen-list
    #define identifier replacement-list
    //第二种,类似函数的宏,好比"预处理阶段的元函数”
    //定义方式如下
    #define identifier(a1,a2,...an) replacement-list
    

    在第二种类似函数的宏定义中,其中每一个ai标识符都命名了一个宏形参(macro parameter),当宏名字出现在后继的程序文本中并且后跟合适的实参列表时(argument list),它将被扩充为replacement-list,而且其中每个出现参数的地方都会被替换为用户给出的实参。[1]

    综上所述,对于TypeName和ClassName这两个宏,(刚好都是三行),第一行就是identifier,第二行第三行都是它的displacement-list,宏在多行的时候需要用\来连接。(这一点和shell编程很像)

    【1】C++模板元编程 David abrahams Aleksey Gurtovoy等 荣耀译

    展开全文
  • 在软件开发过程中,经常有一些常用或者通用的功能或者代码段,这些功能既可以写成函数,也可以封装成为宏定义。那么究竟是用函数好,还是宏定义好?这就要求我们对二者进行合理的取舍。 宏定义中允许包含两行以上...

         先总结和宏和函数的不同之处,以供大家写代码时使用,这段总结摘自《C和指针》一书。

          在软件开发过程中,经常有一些常用或者通用的功能或者代码段,这些功能既可以写成函数,也可以封装成为宏定义。那么究竟是用函数好,还是宏定义好?这就要求我们对二者进行合理的取舍。

    宏定义中允许包含两行以上命令的情形,此时必须在最右边加上”\”且该行”\”后不能再有任何字符,连注释部分都不能有,下面的每行最后的一定要是”\”,”\”后面加一个空格都会报错,更不能跟注释。

      我们来看一个例子,比较两个数或者表达式大小,首先我们把它写成宏定义:

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

      其次,把它用函数来实现:

      int max( int a, int b)

      {

      return (a > b a : b)

      }

      很显然,我们不会选择用函数来完成这个任务,原因有两个:首先,函数调用会带来额外的开销,它需要开辟一片栈空间,记录返回地址,将形参压栈,从函数返回还要释放堆栈。这种开销不仅会降低代码效率,而且代码量也会大大增加,而使用宏定义则在代码规模和速度方面都比函数更胜一筹;其次,函数的参数必须被声明为一种特定的类型,所以它只能在类型合适的表达式上使用,我们如果要比较两个浮点型的大小,就不得不再写一个专门针对浮点型的比较函数。反之,上面的那个宏定义可以用于整形、长整形、单浮点型、双浮点型以及其他任何可以用“>”操作符比较值大小的类型,也就是说,宏是与类型无关的。

      和使用函数相比,使用宏的不利之处在于每次使用宏时,一份宏定义代码的拷贝都会插入到程序中。除非宏非常短,否则使用宏会大幅度增加程序的长度。

      还有一些任务根本无法用函数实现,但是用宏定义却很好实现。比如参数类型没法作为参数传递给函数,但是可以把参数类型传递给带参的宏。

      看下面的例子:

    
      #define MALLOC(n, type) \
      ( (type *) malloc((n)* sizeof(type)))

             利用这个宏,我们就可以为任何类型分配一段我们指定的空间大小,并返回指向这段空间的指针。我们可以观察一下这个宏确切的工作过程:

    int *ptr; 
    ptr = MALLOC ( 5, int );

            将这宏展开以后的结果: 

    ptr = (int ) malloc ( (5) sizeof(int) );

     

    这个例子是宏定义的经典应用之一,完成了函数不能完成的功能,但是宏定义也不能滥用,通常,如果相同的代码需要出现在程序的几个地方,更好的方法是把它实现为一个函数。

     

     

    【转】C语言中DEFINE简介及多行宏定义

    EXample

    define的单行定义

    #define maxi(a,b) (a>;b?a:b)

    define的多行定义

    define可以替代多行的代码,例如MFC中的宏定义(非常的经典,虽然让人看了恶心)

    #define MACRO(arg1, arg2) do { \
    
    \
    
    stmt1; \
    
    stmt2; \
    
    \
    
    } while(0)

    关键是要在每一个换行的时候加上一个 “\ “

    //宏定义写出swap(x,y)交换函数
    
    #define swap(x, y)\
    
    x = x + y;\
    
    y = x - y;\
    
    x = x - y;
    自己写的一个小例子:
    
    
    // 不能加 * 
    应为 指针 
    也是一种类型
    #define  SORT( a,  n)\
    {\
        int i, j;\
        int *t = MALLOC(1,int);\
        for(i=0; i<n-1; i++)\
        {\
            for(j=0; j<n-1-i; j++)\
            {\
                if(*(a+j) > *(a+j+1))\
                {\
                    *t = *(a+j);\
                    *(a+j) = *(a+j+1);\
                    *(a+j+1) = *t;\
                }\
            }\
        }\
    }
    int main(int argc,
    const char * argv[])
    {
        int a=10, b=
    120;
        int data[]={3,200,5};
        //swap(&a, &b);
     
       // sort(data, 3);     //和队列一样:会依据专题的(shi can)参数
    自动识别类型
     
        SORT(data, 3);     
    //会主动用实参
    代替
    形参
    识别类型
     
        for(int i=0;i<3;i++)
        cout << data[i]  << endl;
     
     
        //printf("%d   %d", a, b);
        return 0;
    }

     

    展开全文
  • 在软件开发过程中,经常有一些常用或者通用的功能或者代码段,这些功能既可以写成函数,也可以封装成为宏定义。那么究竟是用函数好,还是宏定义好?这就要求我们对二者进行合理的取舍。 宏定义中允许包含两行以上...

    在软件开发过程中,经常有一些常用或者通用的功能或者代码段,这些功能既可以写成函数,也可以封装成为宏定义。那么究竟是用函数好,还是宏定义好?这就要求我们对二者进行合理的取舍。

    宏定义中允许包含两行以上命令的情形,此时必须在最右边加上”\”且该行”\”后不能再有任何字符,连注释部分都不能有,下面的每行最后的一定要是”\”,”\”后面加一个空格都会报错,更不能跟注释。

      我们来看一个例子,比较两个数或者表达式大小,首先我们把它写成宏定义:

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

      其次,把它用函数来实现:

      int max( int a, int b)

      {

      return (a > b a : b)

      }

      很显然,我们不会选择用函数来完成这个任务,原因有两个:首先,函数调用会带来额外的开销,它需要开辟一片栈空间,记录返回地址,将形参压栈,从函数返回还要释放堆栈。这种开销不仅会降低代码效率,而且代码量也会大大增加,而使用宏定义则在代码规模和速度方面都比函数更胜一筹;其次,函数的参数必须被声明为一种特定的类型,所以它只能在类型合适的表达式上使用,我们如果要比较两个浮点型的大小,就不得不再写一个专门针对浮点型的比较函数。反之,上面的那个宏定义可以用于整形、长整形、单浮点型、双浮点型以及其他任何可以用“>”操作符比较值大小的类型,也就是说,宏是与类型无关的。

      和使用函数相比,使用宏的不利之处在于每次使用宏时,一份宏定义代码的拷贝都会插入到程序中。除非宏非常短,否则使用宏会大幅度增加程序的长度。

      还有一些任务根本无法用函数实现,但是用宏定义却很好实现。比如参数类型没法作为参数传递给函数,但是可以把参数类型传递给带参的宏。

      看下面的例子:

      #define MALLOC(n, type) \
      ( (type *) malloc((n)* sizeof(type)))
    • 1
    • 2

      利用这个宏,我们就可以为任何类型分配一段我们指定的空间大小,并返回指向这段空间的指针。我们可以观察一下这个宏确切的工作过程:

    int *ptr; 
    ptr = MALLOC ( 5, int );

      将这宏展开以后的结果:

    ptr = (int ) malloc ( (5) sizeof(int) );

      这个例子是宏定义的经典应用之一,完成了函数不能完成的功能,但是宏定义也不能滥用,通常,如果相同的代码需要出现在程序的几个地方,更好的方法是把它实现为一个函数。

      下面总结和宏和函数的不同之处,以供大家写代码时使用,这段总结摘自《C和指针》一书。

    【转】C语言中DEFINE简介及多行宏定义

    EXample

    define的单行定义

    #define maxi(a,b) (a>;b?a:b)

    define的多行定义

    define可以替代多行的代码,例如MFC中的宏定义(非常的经典,虽然让人看了恶心)

    \#define   MACRO(arg1,   arg2)   do   {   \ 
       \ 
    stmt1;   \ 
    stmt2;   \ 
       \ 
    }   while(0)    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    关键是要在每一个换行的时候加上一个 “\ “

    //宏定义写出swap(x,y)交换函数
    /#define swap(x, y)\
    x = x + y;\
    y = x - y;\
    x = x - y;
    • 1
    • 2
    • 3
    • 4
    • 5

    自己写的一个小例子:

    // 不能加 * 
    应为 指针 
    也是一种类型
    #define  SORT( a,  n)\
    {\
        int i, j;\
        int *t = MALLOC(1,int);\
        for(i=0; i<n-1; i++)\
        {\
            for(j=0; j<n-1-i; j++)\
            {\
                if(*(a+j) > *(a+j+1))\
                {\
                    *t = *(a+j);\
                    *(a+j) = *(a+j+1);\
                    *(a+j+1) = *t;\
                }\
            }\
        }\
    }
    int main(int argc,
    const char * argv[])
    {
        int a=10, b=
    120;
        int data[]={3,200,5};
        //swap(&a, &b);
    

    // sort(data, 3); //和队列一样:会依据专题的(shi can)参数
    自动识别类型

    SORT(data, <span class="hljs-number" style="color:rgb(0,102,102);"><span class="hljs-number">3</span></span>);     
    

    //会主动用实参
    代替
    形参
    识别类型

    <span class="hljs-keyword" style="color:rgb(0,0,136);"><span class="hljs-keyword">for</span></span>(<span class="hljs-keyword" style="color:rgb(0,0,136);"><span class="hljs-keyword">int</span></span> i=<span class="hljs-number" style="color:rgb(0,102,102);"><span class="hljs-number">0</span></span>;i&lt;<span class="hljs-number" style="color:rgb(0,102,102);"><span class="hljs-number">3</span></span>;i++)
    <span class="hljs-built_in">cout</span> &lt;&lt; data[i]  &lt;&lt; <span class="hljs-built_in">endl</span>;
    
    
    <span class="hljs-comment" style="color:rgb(136,0,0);"><span class="hljs-comment">//printf("%d   %d", a, b);</span></span>
    <span class="hljs-keyword" style="color:rgb(0,0,136);"><span class="hljs-keyword">return</span></span> <span class="hljs-number" style="color:rgb(0,102,102);"><span class="hljs-number">0</span></span>;
    

    }

    展开全文
  • 在1999年版本的ISO C 标准中,可以象函数一样,定义时可以带有可变参数。的语法和函数的语法类似
  • 这个问题是面试中经常遇到的,再一次华为的面试中面试官就问道我这个...预处理,这个阶段主要是将宏定义的符号在源程序中进行替换,比图#define pi 3.1415,这个时期就是将源程序中的所有的pi这样的符号替换为3.1415...

    这个问题是面试中经常遇到的,再一次华为的面试中面试官就问道我这个问题,当时,答的不是很好,甚至有些错误,特此根据自己的理解,总结一下。本人水平不高,有什么错误,欢迎提出!

         首先,我们都知道C++从源代码到执行经过3个大体的步骤: 1.预处理,这个阶段主要是将宏定义的符号在源程序中进行替换,比图#define pi 3.1415,这个时期就是将源程序中的所有的pi这样的符号替换为3.1415,当然,宏还可以定义函数,称为带参的宏,比如#define MAX(a,b) a>b?a:b,在预处理阶段,将源程序中所有的MAX(a,b),这样的部分到替换为a>b?a:b;(在源程序中的a,b是数字或者是其他的类型数据),可见,带参的宏定义的参数是没有类型的。在预编译阶段还要进行文件插入(将头文件中的内容插入到源文件中),删除注释,条件编译。经过预处理的源代码,我们还是可以阅读的,就像自己写的一样,只是进行了一些小的变动。(这一部分基本上说的是宏定义的知识点)。

    如果还想深入了解预编译阶段:http://www.360doc.com/content/18/0102/10/50906870_718321766.shtml

           其次,就是编译阶段,编译阶段主要是词法分析,语法分析这之类的工作,这个阶段就是将经过预处理的文件,最终变成二进制文件的过程,这个阶段在大多数的编译器中,都会将源程序中对inline函数的每一次调用,都以函数的本体来替换,也就像宏定义一样,这样就会增加目标代码的大小,一台内存有限的机器上过度使用inline会造成程序体积太大,即使拥有虚内存,这样也会导致换页行为,这样会带来效率损失。inline这样的替换工作,就将一个普通函数的传参,压栈,返回值这些操作都没有了,因为替换之后,我们在函数调用处的都是代码展开,就像执行一般语句一样。可见,inline与带参的宏的不同就是处理的时间不一样,一个的参数是有类型的,一个的是没有类型的。inline与普通的函数的不同便是,普通函数是有保存现场,传参,执行,返回值,恢复现场,这些开销,而inline是没有的,但是inline函数的做法就是典型的空间换时间,所以,一般将小的常用的函数申明为inline。还有一点,带参的define是简单的符号替换的话,就要慎重地考虑有括号和没有括号的情况了,比如

        

    我推荐一个写的更好的,讲解更详细的博客:

    https://www.cnblogs.com/ht-927/p/4726570.html

    展开全文
  • !... 已经定义了宏定义,为什么在使用的时候会出现未找到函数定义,但有些使用时没问题的,这样的问题怎么解决? ![图片说明](https://img-ask.csdn.net/upload/201705/02/1493718909_361503.png)
  • c++宏定义来编写函数#define

    千次阅读 2017-12-14 22:43:47
    #include&lt;iostream&gt; #include&lt;stdlib.h&gt; #include&lt;assert.h&gt; #include"hello.h" #ifdef _OPENMP #include&lt;omp.h&gt; #endif ... ...
  • c++宏定义一个函数

    万次阅读 2015-09-22 11:20:20
    #define MAX(a,b) ((a)>(b)?...在实际编程中,不推荐把复杂的函数使用,不容易调试。多行用\#define CREATE_FUNC_TYPE(__TYPE__,__PARAM__) \ static __TYPE__* create(__PARAM__ para) \ { \ __TYPE__ *pRet =
  • C++ 如何在宏定义中输出函数

    千次阅读 2016-11-17 09:24:13
    #define CHECK_GL_ERROR(glFunc) \ { \  glFunc; \  char msgBuf[4096]; \  std::string token = #glFunc; \  std::cout } int test_func(int a, int b, int c) {  c = a+ b;...CHECK
  • C++---宏定义代替函数

    2019-11-25 23:36:53
    1.1宏定义函数未定义参数类型,任何操作合法的参数类型都可以传进宏定义中,而函数的参数是与类型有关的;自定义函数有明确的参数类型。 1.2宏定义相较于函数,不需要调用栈,运算速度更快 1.3宏定义只是简单的...
  • C/C++宏定义函数

    千次阅读 2019-05-31 21:38:45
    #include "stdio.h" #define ADD \ int add(int a, int b) \ { \ int c = a+b; \ printf("c=%d\n",c); \ return c; \ } namespace ns { ADD; int a = 2; int b = 3;......
  • C++ 宏定义与空格

    2017-10-10 14:42:00
    C++宏定义中,如果宏是多行,每一行的后面必须加\,而且\后面不能有空格。 查看空格的方法为在vs2005/vs2008中为Ctrl+R+W. 本文转自Work Hard Work Smart博客园博客,原文链接:...
  • 内联(inline)函数 通过inline关键字将函数指定为内联函数,通常就是将它在每个调用点上“内联地”展开(将函数体有关代码嵌入到调用处)。 举个例子: //寻找两个string对象中较短的那个 inline const string &...
  • C++程序设计--宏定义使用--返回值

    千次阅读 2017-09-28 15:29:11
    c++中宏定义返回值
  • 若字符串是表达式,我们称之为函数宏定义,那函数宏定义与普通函数有什么区别呢?我们以下面两行代码为例,展开描述:函数宏定义:#define MAX(a,b) ((a)>(b)?(a):(b))普通函数 :MAX(a,b) { return a>b?a:b;}...
  • C++宏定义中#和##的用法

    千次阅读 2019-11-07 15:33:46
    前段时间很到了宏定义中的新知识:#与##,感觉打开了新天地的大门。 首先来介绍一下这两种功能: # #的用法是负责将其后面的东西转化为字符串,比如: #define TO_STRING(str) #str int main(){ cout << ...
  • 函数模板与宏定义

    2012-04-16 10:54:15
    函数模板与宏定义。代码复用的不同方式的定义,包含了用函数模板实现代码复用,用宏定义展开为函数的定义与使用。
  • C/C++:函数名前引用一个空的宏定义

    千次阅读 2019-02-28 18:05:52
    在很多函数定义的地方都带有空的宏定义 比如:#define NS_CLASS //NS_CLASS的声明,仅仅只是一个定义为空的宏 int NS_CLASS timer_init(struct timer *t, timeout_func_t f, void *data) 查询了相关资料后,应该是多...
  • C++ 宏定义

    万次阅读 多人点赞 2016-10-19 16:28:04
    ———————— #define基本用法 ————————#define命令是C语言中的一个宏定义命令,它用来将一个标识符(宏名)定义为一个字符串,该标识符被称为宏名,被定义的字符串称为替换文本。程序编译之前,编译的...
  • #define DISALLOW_COPY_AND_ASSIGN(TypeName) \ TypeName(const TypeName&){} \ void operator=(const TypeName&){};
  • 最近在看别人的代码的过程中,发现了宏定义代码,由于自己这块之前没有用过,所以编写了示例程序,学习一下宏定义代码。...那有没有一种更加通用的方式呢,宏定义函数给了我们一种选择,示例如下...
  • 什么是宏定义? 通常宏定义的格式为:#define 标识符 字符串 相信大家都见过非常多了,通常我们编译过程中的预处理(预编译)工作又叫宏展开,将代码中的宏名替换为字符串。 为什么要用宏函数? 宏函数虽然在...
  • C++内部函数和外部函数 函数本质上是全局的,因为一个函数要被另外的函数调用,但是,也可以指定函数只能被本文件调用,而不能被其他文件调用。根据函数能否被其他源文件调用,将函数区分为内部函数和外部函数。 ...
  • /* //c++编译器,对源文件的编译实质就是对每个cpp都分别生成....而main.cpp即便包含了所有的其他头文件,依然缺少main.cpp中函数及全局变量的定义,因为只能include头文件并不能include .cpp文件! 因此main.cpp在...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 131,521
精华内容 52,608
关键字:

c++宏定义函数

c++ 订阅