精华内容
下载资源
问答
  • 详细罗列出宏定义和函数调用的区别,很全。。。
  • 尽管函数宏定义和普通函数相比有很多缺点,但只要小心使用还是会显著提高代码的执行效率,毕竟省去了分配释放栈帧、传参、传返回值等一系列工作,因此那些简短并且被频繁调用的函数经常用函数宏定义来代替实现...

    http://www.jb51.net/article/41869.htm

    尽管函数式宏定义和普通函数相比有很多缺点,但只要小心使用还是会显著提高代码的执行效率,毕竟省去了分配和释放栈帧、传参、传返回值等一系列工作,因此那些简短并且被频繁调用的函数经常用函数式宏定义来代替实现

    在C及C++语言中允许用一个标识符来表示一个字符串,称为宏,该字符串可以是常数、表达式、格式串等。在编译预处理时,对程序中所有出现的“宏名”,都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”。宏定义是由源程序中的宏定义命令完成的。宏代换是由预处理程序自动完成的。若字符串是表达式,我们称之为函数式宏定义,那函数式宏定义与普通函数有什么区别呢?

    我们以下面两行代码为例,展开描述:
    函数式宏定义:#define MAX(a,b) ((a)>(b)?(a):(b))
    普通函数 :MAX(a,b) { return a>b?a:b;}

    (1)函数式宏定义的参数没有类型,预处理器只负责做形式上的替换,而不做参数类型检查,所以传参时要格外小心。

    (2)调用真正函数的代码和调用函数式宏定义的代码编译生成的指令不同。

    如果MAX是个普通函数,那么它的函数体return a > b ? a : b; 要编译生成指令,代码中出现的每次调用也要编译生成传参指令和call指令。而如果MAX是个函数式宏定义,这个宏定义本身倒不必编译生成指令,但是代码中出现的每次调用编译生成的指令都相当于一个函数体,而不是简单的几条传参指令和call指令。所以,使用函数式宏定义编译生成的目标文件会比较大。

    (3)函数式宏定义要注意格式,尤其是括号。

    如果上面的函数式宏定义写成 #define MAX(a, b) (a>b?a:b),省去内层括号,则宏展开就成了k = (i&0x0f>j&0x0f?i&0x0f:j&0x0f),运算的优先级就错了。同样道理,这个宏定义的外层括号也是不能省的。若函数中是宏替换为 ++MAX(a,b),则宏展开就成了 ++(a)>(b)?(a):(b),运算优先级也是错了。

    (4)若函数参数为表达式,则普通函数的调用与函数式宏定义的替换过程是不一样的。

    普通函数调用时先求实参表达式的值再传给形参,如果实参表达式有Side Effect,那么这些SideEffect只发生一次。例如MAX(++a, ++b),如果MAX是普通函数,a和b只增加一次。但如果MAX函数式宏定义,则要展开成k = ((++a)>(++b)?(++a):(++b)),a和b就不一定是增加一次还是两次了。所以若参数是表达式,替换函数式宏定义时一定要仔细看好。

    (5)函数式宏定义往往会导致较低的代码执行效率。

    看下面一段代码:

    复制代码 代码如下:

    int a[]={9,3,5,2,1,0,8,7,6,4};
    int max(n)
    {
        return n==0?a[0]:MAX(a[n],max(n-1));
    }

    int main()
    {
        max(9);
        return 0;
    }


    若是普通函数,则通过递归,可取的最大值,时间复杂度为O(n)。但若是函数式宏定义,则宏展开为( a[n]>max(n-1)?a[n]:max(n-1) ),其中max(n-1)被调用了两遍,这样依此递归下去,时间复杂度会很高。

    尽管函数式宏定义和普通函数相比有很多缺点,但只要小心使用还是会显著提高代码的执行效率,毕竟省去了分配和释放栈帧、传参、传返回值等一系列工作,因此那些简短并且被频繁调用的函数经常用函数式宏定义来代替实现。


    http://blog.sina.com.cn/s/blog_861912cd0100tc94.html

    要写好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和指针》一书。


     


    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;


    zigbee里多行define有如下例子

    #define FillAndSendTxOptions( TRANSSEQ, ADDR, ID, LEN, TxO ) { \
    afStatus_t stat;                                                                       \
    ZDP_TxOptions = (TxO);                                                           \
    stat = fillAndSend( (TRANSSEQ), (ADDR), (ID), (LEN) );                   \
    ZDP_TxOptions = AF_TX_OPTIONS_NONE;                                 \
    return stat;                                                                               \
    }

    展开全文
  • 内联函数和宏定义函数区别

    千次阅读 2019-05-17 19:53:55
    1、不同点: 内联函数是在编译时展开,而宏在预编译时展开;在编译的时候,内联函数直接被嵌入到目标代码中去,而宏只是一个简单的文本替换。 ... inline有点类似于宏定义,但是它和宏定义不同...

    1、不同点:

    • 内联函数是在编译时展开,而宏在预编译时展开;在编译的时候,内联函数直接被嵌入到目标代码中去,而宏只是一个简单的文本替换。
    • 内联函数可以进行诸如类型安全检查、语句是否正确等编译功能,宏不具有这样的功能;宏不是函数,而inline是函数。
    • 宏在定义时要小心处理宏参数,一般用括号括起来,否则容易出现二义性。而内联函数不会出现二义性。
    • inline有点类似于宏定义,但是它和宏定义不同的是,宏定义只是简单的文本替换,是在预编译阶段进行的。而inline的引入正是为了取消这种复杂的宏定义的。

    2、举例:

    • 宏定义:
    #define MAX(a,b) ((a)>(b)?(a):(b))
    MAX(a,"Hello"); //错误地比较int和字符串,没有参数类型检查
    • 内联函数:
    #include <stdio.h>
     
    inline int add(int a, int b)
    {
        return (a + b);
    }
    
    int main(void)
    {
        int a;
    
        a = add(1, 2);
        printf("a+b=%d\n", a);
    
        return 0;
    }
    以上a = add(1, 2);处在编译时将被展开为:
    a = (a + b);

    3、使用时的一些注意事项:

    • 使用宏定义一定要注意错误情况的出现,比如宏定义函数没有类型检查,可能传进来任意类型,从而带来错误,如举例。还有就是括号的使用,宏在定义时要小心处理宏参数,一般用括号括起来,否则容易出现二义性
    • inline函数一般用于比较小的,频繁调用的函数,这样可以减少函数调用带来的开销。只需要在函数返回类型前加上关键字inline,即可将函数指定为inline函数。
    • 同其它函数不同的是,最好将inline函数定义在头文件,而不仅仅是声明,因为编译器在处理inline函数时,需要在调用点内联展开该函数,所以仅需要函数声明是不够的。

    4、内联函数使用的条件:

    • 内联是以代码膨胀(复制)为代价,仅仅省去了函数调用的开销,从而提高函数的执行效率。如果执行函数体内代码的时间,相比于函数调用的开销较大,那么效率 的收获会很少。另一方面,每一处内联函数的调用都要复制代码,将使程序的总代码量增大,消耗更多的内存空间。以下情况不宜使用内联: 
    • (1)如果函数体内的代码比较长,使用内联将导致内存消耗代价较高。 
    • (2)如果函数体内出现循环,那么执行函数体内代码的时间要比函数调用的开销大。 
    • 内联不是什么时候都能展开的,一个好的编译器将会根据函数的定义体,自动地取消不符合要求的内联。

    5、使用内联函数和宏函数可能带来的问题(慎用):

    • 有时不要仅是为了提高编程效率而使用这两种函数,要综合考虑后再使用,因为有时使用这两种函数可能带来其他的问题,比如出现问题不能使用gdb调试问题,内联函数不展开,宏函数没有参数检测等

     

     

    展开全文
  • 宏定义和内联函数区别

    千次阅读 2018-01-31 14:59:42
    宏定义和内联函数区别  内联函数是代码被插入到调用者代码处的函数。如同 #define 宏,内联函数通过避免被调用的开销来提高执行效率,尤其是它能够通过调用(“过程化集成”)被编译器优化。 宏定义不检查函数参数...

    宏定义和内联函数区别

     内联函数是代码被插入到调用者代码处的函数。如同 #define 宏,内联函数通过避免被调用的开销来提高执行效率,尤其是它能够通过调用(“过程化集成”)被编译器优化。 宏定义不检查函数参数,返回值什么的,只是展开,相对来说,内联函数会检查参数类型,所以更安全。
      内联函数和宏很类似,而区别在于,宏是由预处理器对宏进行替代,而内联函数是通过编译器控制来实现的。而且内联函数是真正的函数,只是在需要用到的时候,内联函数像宏一样的展开,所以取消了函数的参数压栈,减少了调用的开销。你可以象调用函数一样来调用内联函数,而不必担心会产生于处理宏的一些问题。 
      声明内联函数看上去和普通函数非常相似: 
          void f(int i, char c); 
         
      当你定义一个内联函数时,在函数定义前加上 inline 关键字,并且将定义放入头文件: 
          inline 
          void f(int i, char c) 
          { 
          // ... 
          } 
              
         任何在类的说明部分定义的函数都会被自动的认为是内联函数。 
         内联函数必须是和函数体申明在一起,才有效。像这样的申明Inline Tablefunction(int I)是没有效果的,编译器只是把函数作为普通的函数申明,我们必须定义函数体。 
         Inline tablefunction(int I) {return I*I}; 
         
         这样我们才算定义了一个内联函数。我们可以把它作为一般的函数一样调用。但是执行速度确比一般函数的执行速度要快。 
         我们也可以将定义在类的外部的函数定义为内联函数,比如: 
         Class TableClass{ 
         Private: 
          Int I,j; 
         Public: 
          Int add() { return I+j;}; 
          Inline int dec() { return I-j;} 
          Int GetNum(); 
        } 
        inline int tableclass::GetNum(){ 
        return I; 
        } 
         
         上面申明的三个函数都是内联函数。在C++中,在类的内部定义了函数体的函数,被默认为是内联函数。而不管你是否有inline关键字。 
         内联函数在C++类中,应用最广的,应该是用来定义存取函数。我们定义的类中一般会把数据成员定义成私有的或者保护的,这样,外界就不能直接读写我们类成员的数据了。对于私有或者保护成员的读写就必须使用成员接口函数来进行。如果我们把这些读写成员函数定义成内联函数的话,将会获得比较好的效率。 
         Class sample{ 
          Private: 
           Int nTest; 
          Public: 
           Int readtest(){ return nTest;} 
          Void settest(int I) {nTest=I;} 
         } 
         
         当然,内联函数也有一定的局限性。就是函数中的执行代码不能太多了,如果,内联函数的函数体过大,一般的编译器会放弃内联方式,而采用普通的方式调用函数。这样,内联函数就和普通函数执行效率一样了。

    1.  内联函数

    在C++中我们通常定义以下函数来求两个整数的最大值:

    复制代码 代码如下:

    int max(int a, int b)
    {
     return a > b ? a : b;
    }

    为这么一个小的操作定义一个函数的好处有:

    ① 阅读和理解函数 max 的调用,要比读一条等价的条件表达式并解释它的含义要容易得多

    ② 如果需要做任何修改,修改函数要比找出并修改每一处等价表达式容易得多

    ③ 使用函数可以确保统一的行为,每个测试都保证以相同的方式实现

    ④ 函数可以重用,不必为其他应用程序重写代码

    虽然有这么多好处,但是写成函数有一个潜在的缺点:调用函数比求解等价表达式要慢得多。在大多数的机器上,调用函数都要做很多工作:调用前要先保存寄存器,并在返回时恢复,复制实参,程序还必须转向一个新位置执行

    C++中支持内联函数,其目的是为了提高函数的执行效率,用关键字 inline 放在函数定义(注意是定义而非声明,下文继续讲到)的前面即可将函数指定为内联函数,内联函数通常就是将它在程序中的每个调用点上“内联地”展开,假设我们将 max 定义为内联函数:

    复制代码 代码如下:

    inline int max(int a, int b)
    {
     return a > b ? a : b;
    }

    则调用: cout<<max(a, b)<<endl;


    在编译时展开为: cout<<(a > b ? a : b)<<endl;

    从而消除了把 max写成函数的额外执行开销

    2.  内联函数和宏

    无论是《Effective C++》中的 “Prefer consts,enums,and inlines to #defines” 条款,还是《高质量程序设计指南——C++/C语言》中的“用函数内联取代宏”,宏在C++中基本是被废了,在书《高质量程序设计指南——C++/C语言》中这样解释到:

    3.  将内联函数放入头文件

    关键字 inline 必须与函数定义体放在一起才能使函数成为内联,仅将 inline 放在函数声明前面不起任何作用。

    如下风格的函数 Foo 不能成为内联函数:

    复制代码 代码如下:

    inline void Foo(int x, int y);   // inline 仅与函数声明放在一起   
    void Foo(int x, int y)
    {
     ...

    而如下风格的函数 Foo 则成为内联函数:

    复制代码 代码如下:

    void Foo(int x, int y);   
    inline void Foo(int x, int y)   // inline 与函数定义体放在一起
    {
     ...

    所以说,C++ inline函数是一种“用于实现的关键字”,而不是一种“用于声明的关键字”。一般地,用户可以阅读函数的声明,但是看不到函数的定义。尽管在大多数教科书中内联函数的声明、定义体前面都加了 inline 关键字,但我认为 inline 不应该出现在函数的声明中。这个细节虽然不会影响函数的功能,但是体现了高质量C++/C 程序设计风格的一个基本原则:声明与定义不可混为一谈,用户没有必要、也不应该知道函数是否需要内联。

    定义在类声明之中的成员函数将自动地成为内联函数,例如:

    复制代码 代码如下:

    class A
    {  
    public:
     void Foo(int x, int y) { ... }   // 自动地成为内联函数  

    但是编译器是否将它真正内联则要看 Foo函数如何定义

    内联函数应该在头文件中定义,这一点不同于其他函数。编译器在调用点内联展开函数的代码时,必须能够找到 inline 函数的定义才能将调用函数替换为函数代码,而对于在头文件中仅有函数声明是不够的。

    当然内联函数定义也可以放在源文件中,但此时只有定义的那个源文件可以用它,而且必须为每个源文件拷贝一份定义(即每个源文件里的定义必须是完全相同的),当然即使是放在头文件中,也是对每个定义做一份拷贝,只不过是编译器替你完成这种拷贝罢了。但相比于放在源文件中,放在头文件中既能够确保调用函数是定义是相同的,又能够保证在调用点能够找到函数定义从而完成内联(替换)。

    但是你会很奇怪,重复定义那么多次,不会产生链接错误?

    我们来看一个例子:

    A.h :

    复制代码 代码如下:

    class A
    {
    public:
     A(int a, int b) : a(a),b(b){}
     int max();

    private:
     int a;
     int b;
    };

    A.cpp : 

    复制代码 代码如下:

    #include "A.h"

    inline int A::max()
    {
     return a > b ? a : b;
    }

    Main.cpp : 

    复制代码 代码如下:

    #include <iostream>
    #include "A.h"
    using namespace std;

    inline int A::max()
    {
     return a > b ? a : b;
    }

    int main()
    {
     A a(3, 5);
     cout<<a.max()<<endl;
     return 0;
    }

    一切正常编译,输出结果:5

     


    倘若你在Main.cpp中没有定义max内联函数,那么会出现链接错误:

    error LNK2001: unresolved external symbol "public: int __thiscall A::max(void)" (?max@A@@QAEHXZ)main.obj
    找不到函数的定义,所以内联函数可以在程序中定义不止一次,只要 inline 函数的定义在某个源文件中只出现一次,而且在所有源文件中,其定义必须是完全相同的就可以。

    在头文件中加入或修改 inline 函数时,使用了该头文件的所有源文件都必须重新编译。

    4.  慎用内联

    内联虽有它的好处,但是也要慎用,以下摘自《高质量程序设计指南——C++/C语言》:

    而在Google C++编码规范中则规定得更加明确和详细:

    内联函数:

    Tip: 只有当函数只有 10 行甚至更少时才将其定义为内联函数.

    定义: 当函数被声明为内联函数之后, 编译器会将其内联展开, 而不是按通常的函数调用机制进行调用.
    优点: 当函数体比较小的时候, 内联该函数可以令目标代码更加高效. 对于存取函数以及其它函数体比较短, 性能关键的函数, 鼓励使用内联.
    缺点: 滥用内联将导致程序变慢. 内联可能使目标代码量或增或减, 这取决于内联函数的大小. 内联非常短小的存取函数通常会减少代码大小, 但内联一个相当大的函数将戏剧性的增加代码大小. 现代处理器由于更好的利用了指令缓存, 小巧的代码往往执行更快。
    结论: 一个较为合理的经验准则是, 不要内联超过 10 行的函数. 谨慎对待析构函数, 析构函数往往比其表面看起来要更长, 因为有隐含的成员和基类析构函数被调用!
    另一个实用的经验准则: 内联那些包含循环或 switch 语句的函数常常是得不偿失 (除非在大多数情况下, 这些循环或 switch 语句从不被执行).
    有些函数即使声明为内联的也不一定会被编译器内联, 这点很重要; 比如虚函数和递归函数就不会被正常内联. 通常, 递归函数不应该声明成内联函数.(递归调用堆栈的展开并不像循环那么简单, 比如递归层数在编译时可能是未知的, 大多数编译器都不支持内联递归函数). 虚函数内联的主要原因则是想把它的函数体放在类定义内, 为了图个方便, 抑或是当作文档描述其行为, 比如精短的存取函数.

    -inl.h文件:


    Tip: 复杂的内联函数的定义, 应放在后缀名为 -inl.h 的头文件中.


    内联函数的定义必须放在头文件中, 编译器才能在调用点内联展开定义. 然而, 实现代码理论上应该放在 .cc 文件中, 我们不希望 .h 文件中有太多实现代码, 除非在可读性和性能上有明显优势.

    如果内联函数的定义比较短小, 逻辑比较简单, 实现代码放在 .h 文件里没有任何问题. 比如, 存取函数的实现理所当然都应该放在类定义内. 出于编写者和调用者的方便, 较复杂的内联函数也可以放到 .h 文件中, 如果你觉得这样会使头文件显得笨重, 也可以把它萃取到单独的 -inl.h 中. 这样把实现和类定义分离开来, 当需要时包含对应的 -inl.h 即可。



    展开全文
  • 要写好C语言,漂亮的宏定义是非常重要的。宏定义可以帮助我们防止出错,提高代码的可移植性可读性等。
  • 若字符串是表达式,我们称之为函数宏定义,那函数宏定义与普通函数有什么区别呢?我们以下面两行代码为例,展开描述:函数宏定义:#define MAX(a,b) ((a)>(b)?(a):(b))普通函数 :MAX(a,b) { return a>b?a:b;}...
  • 带参宏定义和函数区别

    千次阅读 2017-02-21 16:59:36
    本质区别展开仅仅是字符串的替换,不会对表达式进行计算,在编译之前就被处理掉了,他没有机会参与编译,也不会占用内存。而函数是一段可以重复使用的代码,会被编译,会给他分配内存,每次调用函数就是执行...

    本质区别:宏展开仅仅是字符串的替换,不会对表达式进行计算,宏在编译之前就被处理掉了,他没有机会参与编译,也不会占用内存。而函数是一段可以重复使用的代码,会被编译,会给他分配内存,每次调用函数就是执行这块内存中的代码。
    eg1:用函数计算平方值

        #include <stdio.h>
        int SQ(int y){
          return ((y)*(y));
        }
        int main(){
            int i=1;
            while(i<=5){
                printf("%d^2 = %d\n", (i-1), SQ(i++));
            }
            return 0;
        }

    运行结果:
    1^2 = 1
    2^2 = 4
    3^2 = 9
    4^2 = 16
    5^2 = 25
    eg2:用宏计算平方值:

    include <stdio.h>
    #define SQ(y) ((y)*(y))
    int main(){
        int i=1;
        while(i<=5){
            printf("%d^2 = %d\n", i, SQ(i++));
        }
        return 0;
    }

    在 VS2010 和 C-Free 5.0 下的运行结果:
    3^2 = 1
    5^2 = 9
    7^2 = 25
    在示例①中,先把实参 i 传递给形参 y,然后再自增 1,这样每循环一次 i 的值增加 1,所以最终要循环 5 次。
    在示例②中,宏调用只是简单的字符串替换,SQ(i++) 会被替换为 ((i++)*(i++)),这样每循环一次 i 的值增加 2,所以最终只循环 3 次。
    带参数的宏也可以用来定义多个语句,在宏调用时,把这些语句又替换到源程序中,请看下面的例子:
    由此可见,宏和函数只是在形式上相似,本质上是完全不同的。

        #include <stdio.h>
        #define SSSV(s1, s2, s3, v) s1 = length * width; s2 = length * height; s3 = width * height; v = width * length * height;
        int main(){
            int length = 3, width = 4, height = 5, sa, sb, sc, vv;
            SSSV(sa, sb, sc, vv);
            printf("sa=%d, sb=%d, sc=%d, vv=%d\n", sa, sb, sc, vv);
            return 0;
        }

    运行结果:
    sa=12, sb=15, sc=20, vv=60

    展开全文
  • 宏定义和内联函数区别

    千次阅读 2019-03-08 22:10:19
    一、宏定义和内联函数区别 1. 宏定义不是函数,但是使用起来像函数。预处理器用复制宏代码的方式代替函数的调用,省去了函数压栈退栈过程,提高了效率。 内联函数本质上是一个函数,内联函数一般用于函数体的...
  • 带参数宏定义和函数区别

    千次阅读 2013-04-03 21:14:00
    #define S(a,b) a*b area=S(3,2) int S(int a,int b) { int s; ...这两个有什么区别 ...尽量少使用宏定义宏定义是把S(a,b)简单地替换成a*b 这样会产生问题,最典型的两种: 1.缺括号,比如aer
  • 函数宏定义和普通函数区别

    千次阅读 2016-08-29 16:22:47
    在C及C++语言中允许用一个标识符来表示一个字符串,称为宏,该字符串可以是常数、表达式、格式...若字符串是表达式,我们称之为函数宏定义。 我们以下面两行代码为例,展开描述: 函数宏定义:#define MAX(a,b)
  • 比较函数宏定义和普通函数区别函数宏定义:#define MAX(a,b) ((a)>(b)?(a):(b)) 普通函: MAX(a,b) { return a>b?a:b;}   (1)函数宏定义的参数没有类型,预处理器只负责做形式上的替换,而不做...
  • 带参宏定义和函数调用的区别

    千次阅读 2018-09-15 22:15:47
    1.函数调用时,先求出实参表达式的值,然后带入形参...3.对函数中的实参形参都要定义类型,二者的类型要求一致,如不一致,应进行类型转换;而不存在类型问题,宏名无类型,它的参数也无类型,只是一个符号代表...
  • 宏定义函数和普通函数

    千次阅读 2017-06-04 16:21:23
    预处理阶段进行简单的文本替换,没有入栈、出栈、参数传递函数返回等等工作,执行效率明显高于普通函数,因此,简短并且被频繁调用的函数经常用宏定义函数来代替实现 没有参数检查,会影响程序安全 如果函数比较...
  • 宏定义函数与普通函数的区别

    千次阅读 2017-10-17 23:23:48
    #define MAX(a,b) ((a)>(b)?(a):(b)) int MAX1(int a,int b) { return a>b?a:b; ...1)宏定义函数没有参数类型也不做类型检查,预编译...2)宏定义函数时一定要注意括号的存在匹配,有时会因为 括号的不存在就会导致
  • 宏定义和内联函数

    千次阅读 2013-09-11 23:26:00
    宏定义和内联函数,都可以减少函数的调用开销,每次调用函数不必压栈开辟新的空间。使用宏定义和内联函数代码的执行效率高。它们的区别是 (1)宏定义是预编译器加载,而内联函数是由编译器加载; (2)宏定义...
  • 宏定义可以帮助我们防止出错,提高代码的可移植性可读性等。  在软件开发过程中,经常有一些常用或者通用的功能或者代码段,这些功能既可以写成函数,也可以封装成为宏定义。那么究竟是用函数好,还是宏定义好?...
  • 2.编译器会对内联函数的参数类型做安全检查或自动类型转换(同普通函数),而宏定义则不会; 3.内联函数可以访问类的成员变量,宏定义则不能; 4.在类中声明同时定义的成员函数,自动转化为内联函数。文章(一)内联...
  • 内联函数和宏定义区别

    千次阅读 2014-03-06 11:46:02
    2.编译器会对内联函数的参数类型做安全检查或自动类型转换(同普通函数),而宏定义则不会;  3.内联函数可以访问类的成员变量,宏定义则不能;  4.在类中声明同时定义的成员函数,自动转化为内联函数。 内联...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 321,577
精华内容 128,630
关键字:

宏定义和函数的区别