精华内容
下载资源
问答
  • 要写好C语言,漂亮的定义是非常重要的。定义可以帮助我们防止出错,提高代码的可移植性和可读性等。
  • c语言宏函数怎么传递宏参数We can define a function like Macro, in which we can pass the arguments. When a Macro is called, the Macro body expands or we can say Macro Call replaces with Macro Body. ...

    c语言宏函数怎么传递宏参数

    We can define a function like Macro, in which we can pass the arguments. When a Macro is called, the Macro body expands or we can say Macro Call replaces with Macro Body.

    我们可以定义一个函数,例如Macro,可以在其中传递参数。 调用宏时,宏主体会展开,或者可以说宏调用被宏主体替换

    Now, the important thing is that: How Macro arguments evaluate? - "Macro arguments do not evaluate before Macro expansion, they evaluate after the expansion."

    现在,重要的是: 宏参数如何计算? - “宏参数在宏扩展之前不评估,而在扩展之后评估。”

    Consider the example:

    考虑示例:

    #include <stdio.h>
    
    #define CALC(X,Y) (X*Y)
    
    int main()
    { 
    	printf("%d\n",CALC(1+2, 3+4));
    	return 0;
    }
    
    

    Output

    输出量

    11
    
    

    Explanation:

    说明:

    If you are thinking that 1+2 and 3+4 will be evaluated before the expansion and it will be expanded as 3*7 then, you are wrong.

    如果您认为在扩展之前将对1 + 2和3 + 4进行求值,并且将其扩展为3 * 7,那么您错了。

    The arguments evaluate after the call, thus Macro CALC(1+2,3+4) will be expanded as = (1+2*3+4) = (1+6+4) =(11).

    参数在调用后求值,因此Macro CALC(1 + 2,3 + 4)将扩展为=(1 + 2 * 3 + 4)=(1 + 6 + 4)=(11)

    Finally, the output will be 11.

    最后, 输出将为11

    翻译自: https://www.includehelp.com/c-programs/macro-arguments-evaluation-in-c.aspx

    c语言宏函数怎么传递宏参数

    展开全文
  • C语言基础--宏函数

    千次阅读 2020-06-07 15:43:45
    C语言基础–宏函数 1. 函数和数据类型 函数式宏(宏函数)和函数类比会更加灵活,我们通过两个例子来看一下。 函数 #include <stdio.h> int sqr_int(int x) { return x*x; } double sqr_double(double x) { ...

    C语言基础–宏函数

    1. 函数和数据类型

    1. 函数式宏(宏函数)和函数类比会更加灵活,我们通过两个例子来看一下。

      函数

      #include <stdio.h>
      int sqr_int(int x)
      {
          return x*x;
      }
      
      double sqr_double(double x)
      {
          return x*x;
      }
      
      int main(int argc , char *argv[])
      {
          int n;
          double x;
          
          printf("请输入一个整数:\n");
          scanf("%d",&n);
          printf("%d的平方是:%d\n",n,sqr_int(n));
          
          printf("请输入一个实数:\n");
          scanf("%lf",&n);
          printf("%lf的平方是:%lf\n",n,sqr_double(n));
          
          return 0;
      }
      
      • 当然了,如果计算long int,或者long long int型的数据类型的话我们还得编写该类型的函数。可以 遇见,如果这样下去代码中将会充斥着大量功能相近,名称相似的函数,看起来非常糟糕。
      • 下面来看一下函数式宏的实现:

      函数式宏

      #include <stdio.h>
      
      #define sqr(x) ((x)*(x))
      
      int main(int argc,char *argv[])
      {
          int n;
          double x;
          
          printf("请输入一个整数:\n");
          scanf("%d",&n);
          printf("%d的平方是:%d\n",n,sqr(n));
          
          printf("请输入一个实数:\n");
          scanf("%lf",&n);
          printf("%lf的平方是:%lf\n",n,sqr(n));
          
          return 0;
      }
      
      • 可以看到一个简单的宏函数就实现了几个函数才能实现的事情,当然了宏函数可不止这点儿能耐。
      • 本例中类似sqr(@) —>展开为((@)*(@))的形式就称为宏展开
      • 当调用该宏函数的时候,就会在调用位置将该宏函数展开为上述形式。
      • 值得注意的是宏定义只做替换不做计算,这一点很重要,后面会再提到。

    2. 函数和函数式宏

    • 从上面可以看到函数式宏在某些时候可以替代函数的作用,它们的区别如下:
    1. 函数式宏是在编译时展开并填入程序的

    2. 而函数定义则需要为每个形参都定义各自的数据类型,返回值类型也只能为一种。函数更为严格。

    3. 函数默默的为我们进行一些复杂的操作,比如:

      1. 参数传递(将实参值赋值给形参)
      2. 函数调用和函数返回操作
      3. 返回值的传递

      而函数式宏只是做宏展开,并不做上述处理。

    4. 函数式宏能是程序的运行速度稍微提高一点儿,但是当函数中有大量的宏替换的时候,又会使得程序变得臃肿。(原理是宏函数只做替换,并没有类似函数调用的跳转、参数出入栈等操作,自然会提高函数的运行速度。这种运行速度加快体验在大量使用的时候尤为明显)

    5. 宏在使用的时候必须小心谨慎,避免出现问题。这一点是有宏的本身特性决定,即只做替换不做计算。举例来说明:

      宏的副作用

      情况一:

      #define sqr(a) ((a)*(a))
      

      若调用该函数式宏计算sqr(a++),展开后就变为:((a++) * (a++)),可以发现a执行了两次自增操作。这就会造成隐形的错误,比如我只是想将a自增1后在求其平方,但是结果却并非我们所想。

      情况二:

      宏定义与宏函数

      假如我们在sqr 和’('之间多敲了一个空格,如下

      #define sqr (a) ((a)*(a))
      

      那么此时函数式宏就变成了,宏定义了,也成对象式宏。即sqr会被编译器替换成(x) (x)*(x)

      在定义宏函数的时候注意宏函数名和’('之间不能有空格。

      情况三:

      #define sum(x,y) x + y	//注意:不规范的函数式宏的定义
      
      //调用
      z = sum(a,b) * sum(c,d);
      //编译器将其展开后就变为:
      z = a + b * c + d;	//这样是不是偏离了我们的本意
      

      因此,我们在定义函数式宏的时候与一定要每个参数以及整个表达式都用()括起来,就不会出错了。上面的就可以改为

      #define sum(x,y) ((x) + (y))	//正确的定义方法
      //调用
      z = sum(a,b) * sum(c,d);
      /编译器将其展开后就变为:
      z = ((a) + (b)) * ((c) + (d));
      

      总结,在定义和使用函数式宏的时候要注意避免其产生副作用

    3. 不带参数的函数式宏

    • 函数式宏也可以像函数那样不带参数

      #define my_print() (printf("你好啊!\n"))
      

    4. 函数式宏和逗号表达式

    • 下面将说明函数式宏使用时的一个重要技巧
    #include <stdio.h>
    
    #define puts_alert(str)  {putchar('\a');puts(str);}
    
    int main(int argc,char *argv[])
    {
        int n;
        
        printf("请输入一个整数:");
        scanf("%d",&n);
        
        if(n)
            puts_alert("这个数不是0.");
        else
            puts_alert("这个数是0.");
        
        return 0;
    }
    
    • 当我们运行这个程序的时候会报错,无法运行。提示else 缺少if

      因为将该函数式宏展开后就变为:

    #include <stdio.h>
    
    #define puts_alert(str)  {putchar('\a');puts(str);}
    
    //当然了,如果一行定义不下,有时候为了美观我们也这样写,'\'表示下一行还有内容
    #define puts_alert(str)  {putchar('\a'); 	\
    						   puts(str);}
    
    int main(int argc,char *argv[])
    {
        int n;
        
        printf("请输入一个整数:");
        scanf("%d",&n);
        
        if(n)
            {putchar('\a');puts(str);};
        else
            {putchar('\a');puts(str);};
        
        return 0;
    }
    
    • 很明显,if下的复合语句’}‘后的’;‘会被认为是空语句,那么此时else再去找它上面的那个if的时候就找不到了,因此就会报错。当然了函数式宏中的’{}'也不能少,若少了又会报其他的错误。怎么解决呢?可以思考一下。当然了,也可以参见下面一节

    5. 函数式宏和逗号表达式

    • 上面一节我们看到了当函数式宏中有多条需要执行的语句的时候我么遇到了麻烦,下面各处解决方法:
    #include <stdio.h>
    
    #define puts_alert(str)  (putchar('\a'),puts(str))
    
    int main(int argc,char *argv[])
    {
        int n;
        
        printf("请输入一个整数:");
        scanf("%d",&n);
        
        if(n)
            puts_alert("这个数不是0.");
        else
            puts_alert("这个数是0.");
        
        return 0;
    }
    
    //在if处展开
        if(n)
            (putchar('\a'),puts(str));
        else
            (putchar('\a'),puts(str));
    
    • 这里有个知识点,逗号表达式。逗号运算符:

      表达式a,表达式b —> 按顺序判断a和b,整个表达式最终生成表达式b的判断结果。当然了,若有多个表达式(整个逗号表达式的值为最后一个表达式的值),可以以此类推。

      举个例子:

      int a = 3,b = 4,z = 0;
      z = ++a,++b;	
    //执行时a的值会自增1,b的值也会自增1,最终将b自增后的值赋给变量z
    //此时z的值为5,也就是最终整个逗号表达式的结果。
    

    可以看到:整个逗号表达式中每个语句都会被计算到

    如果想要了解更多的逗号表达式的知识可以参考下我的另一博文:
    逗号运算符与逗号表达式

    6. 总结

    • 函数式宏在使用时很方便,正确使用的话不仅可以使得我们的程序变得简洁,而且可以提高我们程序的运行速度。
    • 但是这种方式有时也很容易出错,所以我们在使用的时候一定要非常小心,避免出错。
    展开全文
  • C语言_宏函数_换行符

    2021-11-01 14:39:39
    在写代码时,发现很多代码重复,为了缩减代码及利于代码维护,将重复的代码通过宏函数的方式进行定义。 简单地将重复代码拷贝出来,通过宏定义封装了一下;因为多行代码,通过换行符进行了规范。使用了宏函数之后...

    在写代码时,发现很多代码重复,为了缩减代码及利于代码维护,将重复的代码通过宏函数的方式进行定义。

    简单地将重复代码拷贝出来,通过宏定义封装了一下;因为多行代码,通过换行符进行了规范。使用了宏函数之后发现代码无效了,找了半天宏函数的定义规则,查阅自己的代码,也没有发现什么问题。把宏函数封装的代码替换回去就好用。

    最终发现了问题:宏函数的实现部分有 // 函数注释,导致在这之后的代码全部作为注释进行了处理。

    例如:下面宏函数,有效代码只有在 // 之前的代码有效。

    #define DEF_FUNC()             \
    c = a+b;                       \
    // 函数注释                     \
    ....

    展开全文
  • C语言定义函数

    万次阅读 多人点赞 2019-03-18 11:40:46
    通过一个比较函数的例子来说明宏函数和普通函数的区别: 宏函数形式: #define MAX( a, b) ( (a) &gt; (b) (a) : (b) ) //这里为什么有这么多括号,后面会讲 普通函数形式: int max(int a, int b) { ...

    通过一个比较函数的例子来说明宏函数和普通函数的区别:

    宏函数形式:

    #define MAX( a, b) ( (a) > (b) (a) : (b) ) //这里为什么有这么多括号,后面会讲

    普通函数形式:

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

    宏函数

    优点:节省空间(给形参节省)

    缺点:浪费时间(主要浪费在编译时);没有语法检查,不安全。

    普通函数

    优点:有语法检查

    缺点:浪费空间。


    注意宏函数在调用时只是对函数中的变量做简单的替换,注意这里的替换真的是替换,非常死板的那种!!!

    可以看一下下面的例子:

    #define SQUARE_SUM(x,y) x*x+y*y
    #include <stdio.h>
    
    int main()
    {
        int i = 1,j = 2,k ;
        k = SQUARE_SUM(i+1,j);
        printf("%d",k);
        return 0;
    }

    很多人可能会这样算:2*2+2*2=8,这样其实是错误的。

    看一下程序运行的结果:

    原因是程序只是做了替换,也就是1+1*1+1+2*2=7

    现在知道为什么要在宏函数定义时加这么多括号了吧 (= =)

    想达到结果为8的效果应该这样写:

    #define SQUARE_SUM(x,y) (x)*(x)+(y)*(y) //注意这里的括号!!
    #include <stdio.h>
    
    int main()
    {
        int i = 1,j = 2,k ;
        k = SQUARE_SUM(i+1,j);
        printf("%d",k);
        return 0;
    }

    运行结果:

    OK! 大功告成!

    展开全文
  • C语言宏定义、宏函数、内置宏与常用宏

    万次阅读 多人点赞 2018-09-30 17:48:43
    C语言(C++)特有的两把双刃剑指针和宏定义/宏函数使得C语言在底层开发中披荆斩棘、无所不能。这两个概念涉及范围比较广,其分支点也比较多,可谓星罗棋布,但这每颗星都足以照亮C语言因其开发周期、可维护性、可...
  • C语言宏接收函数及其参数

    千次阅读 2016-04-08 10:03:34
    C语言宏接收函数及其参数标签:c/c++#include #include <stdlib.h>#define call_optimized(function, arguments) {\ printf("\n-------------"); \ printf("\n\tCALL %s\n", #function); \ function argument
  • C语言 返回值

    千次阅读 2018-07-25 16:48:24
    宏函数(块结构表达式) 可以代替一段函数,而且有返回值。 #include &amp;amp;lt;stdio.h&amp;amp;gt; #define kaddr(addr)\ ({\ int tmp = addr;\ if (addr &amp;amp;gt; 5) \ tmp = 2;\ else\ ...
  • 尽管函数定义和普通函数相比有很多缺点,但只要小心使用还是会显著提高代码的执行效率,毕竟省去了分配和释放栈帧、传参、传返回值等一系列工作,因此那些简短并且被频繁调用的函数经常用函数定义来代替实现...
  • 内联函数本质上是两个不同的概念如果程序编写者对于既要求快速,又要求可读的情况下,则应该将函数冠以inline
  •  在软件开发过程中,经常有一些常用或者通用的功能或者代码段,这些功能既可以写成函数,也可以封装成为定义。那么究竟是用函数好,还是定义好?这就要求我们对二者进行合理的取舍。  定义中允许包含两行...
  • 写好C语言,漂亮的定义很重要,使用定义可以防止出错,提高可移植性,可读性,方便性 等等。
  • C语言_定义

    万次阅读 多人点赞 2019-02-02 00:20:03
      编译一个C语言程序的第一步骤就是预处理阶段,这一阶段就是发挥作用的阶段。C预处理器在源代码编译之前对其进行一些文本性质的操作,主要任务包括删除注释、插入被#include进来的文件内容、定义和替换由#...
  • c语言宏定义函数如何调用

    千次阅读 2015-09-22 10:20:24
     使用宏函数或者宏函数时,注意如下几点:  (1)宏函数的参数没有类型,预处理器只负责做形式上的替换,而不做参数类型检查,所以传参时要格外小心。  (2)宏函数定义要注意格式,尤其是括号。 ...
  • 宏在预处理阶段会被编译器替换掉,而且宏一般只做简单的文本替换...对于宏函数,我们可能比较陌生,下面举例来介绍一下宏函数: #define SQUARE(x) ((x)*(x)) int main() { int input; printf("Please input:"); ...
  • 关于C语言宏定义#define 最常用的莫过于通过宏定义定义常数了,例如#define MAX 1000 通过宏定义程序中需要的常量,方便维护被多次引用的变量,并且宏替换在预处理阶段完成,程序运行是被替换为确定的值。...
  • C语言宏定义用法大全

    2018-06-11 22:12:36
    关于C语言宏定义的用法,作了一个总结,除了常用宏定义外,还有类似函数的宏的用法
  • 您可能感兴趣的文章:详解C语言中的#define宏定义命令用法简单讲解C语言中宏的定义与使用如何在C语言的宏中使用类型关键字C语言中的内联函数(inline)与宏定义(#define)详细解析C语言中宏定义使用的小细节C语言宏定义...
  • C语言宏的用法详解

    千次阅读 多人点赞 2019-06-28 08:55:17
    主要有两种,他们的区别主要是在使用上面,一种是在使用时类似于数据对象称为Object-like,另一种在使用时类似于函数调用称为Function-like。在C语言使用#define来定义 你可以将任意的有效的标识符定义为,...
  • 文章目录一、typeof 关键字二、snprintf()函数的作用三、__builtin_expect的作用四、C语言中常用的预定义五、反斜杠的作用 一、typeof 关键字   如果你是 C++ 程序员,应该接触过 C++11 里的 decltype 操作符,它...
  • C语言中宏定义技巧.doc
  • C 语言允许带有参数。在定义中的参数称为形式参数,在调用中的参数称为实际 参数。 对带参数的,在调用中,不仅要展开,而且要用实参去代换形参。 带参定义的一般形式为: #define 宏名(形参列表) 字符...
  • C语言自定义打印宏函数

    千次阅读 2018-08-27 22:29:14
    宏函数实现在头文件中,加上了打印级别来控制打印是否输出,打印级别的设定需在调用的.c文件中自定义(这样做是为了能实现不同文件的打印级别能不一样,在调试指定文件或模块的问题是,能起到屏蔽其他无关代码打印的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 109,785
精华内容 43,914
关键字:

c语言宏函数

c语言 订阅