C语言宏定义讲解

版权声明:本文为QMec原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_41995541/article/details/89646055

摘要

详细讲解了C语言的两大宏定义

不带参数的宏定义:

  • 用一个指定的标识符(即名字)来代表一个字符串。
#define 标识符 字符串   //标识符会被字符串所替代

//eg:定义符号常量#define PI 3.1415926
  • 作用:

    • 在本程序文件中用指定的标识符PI来代替"3.1415926”这个字符串。在进行预处理时,将程序中凡是在该指令以后出现的所有的"P"都用"3.1415926"代替。这种方法使用户能以一个简单的名字代替一个长的字符串,因此把这个标识符(名字)称为“宏名”,在预处理时将宏名替换成字符串的过程称为“宏展开”。 #define就是宏定义指令。一改全改
  • 说明:

    1. 宏定义只是用宏名代替一个字符串,也就是只作简单的置换,不作正确性检查。如果写成#define PI 3. 1415926即把数字 1 错写成小写字母 1,在预处理时也照样把字母 l 代入,不管是否符合用户原意,也不管含义是否有意义。预处理时不作任何语法检查。只有对已被宏展开后的源程序进行编译时才会发现语法错误并报错。

    2. 宏定义不是C语句,不必在行末加分号。如果加了分号则会连分号一起进行置换。

      //eg:
      #define  PI  3.1415926;
      area=PI*r*r;
      area=3.1415926;*r*r;    //显然出现语法错误。
      
  • 宏定义作用域:

    • #define指令出现在程序中的函数的外面,宏名的有效范围为该指令行起到本源文件结束。通常,#define指令写在文件开头,函数之前,作为文件一部分,在整个文件范围内有效。

    • 可以用==#undef指令==终止宏定义的作用域。这样可以灵活控制宏定义的作用范围。

    • 在进行宏定义时,可以引用已定义的宏名,即可以层层置换。

    • 对程序中用双撇号括起来的字符串内的字符,即使与宏名相同,也不进行置换。

    • 宏定义与定义变量的含义不同,不分配存储空间。不带参数的宏定义只作简单的字符替换,千万不要把宏名当作变量名使用。

带参数的宏定义:

  • 带参数的宏定义不是进行简单的字符串替换,还要进行参数替换。
#define   宏名(参数表)   字符串 

//以空格区别宏名和字符串,字符串中包含在括号中所指定的参数。
//例如:
# define  S(a,b)  a*b
:
area=S(3,2); //→ area=3*2;
  • 说明:
    • 对带参数的宏的展开只是将语句中的宏名后面括号内的实参字符串代替#define指令中的形参
#define  S(r)  PI*r*r
area=S(a+b);  //→ area=PI*a+b*a+b;
#define  S(r)  PI*(r)*(r)
area=S(a+b);  //→ area=PI*(a+b)*(a+b);

  • 注意:

    • 在定义宏时,在宏名与带参数的括号之间不应加空格;否则将空格以后的字符都作为替代字符串的一部分。以空格区别宏名和字符串
    //eg:
    #define  S  (r)  PI*r*r   //在S后有一空格
    area=S(a);  //→ aArea=(r) Pl*r*r(a);  //显然有错
    
    
    • 系统会认为S是符号常量(不带参数的宏名),它代表字符串“® PI*r*r"。
  • 带参数的宏定义和函数之间有一定类似之处,在调用函数时也是在函数名后的括号内写实参,也要求实参与形参的数目相等。

    • 本质上的区别有:
    • 函数调用时,先求出实参表达式的值,然后代入形参,而使用带参数的宏只是进行字符替换。
    • 函数调用是在程序运行时处理的,为形参分配临时的内存单元。而宏置换则是在预处理阶段进行的,在置换时并不分配内存单元,不进行值的传递处理,也没有“返回值”的概念。
    • 对函数中的实参和形参都要定义类型,二者的类型要求一致,如不一致,应进行类型转换。而宏不存在类型问题,宏名无类型,它的参数也无类型,只是一个符号代表,置换时,代入指定的字符串即可。定义宏时,字符串可以是任何类型的数据。
    • 调用函数只可得到一个返回值,而用宏可以设法得到几个结果。
    • 使用宏次数多时,宏展开后源程序变长,因为每展开一次都使程序增长,而函数调用不会使源程序变长。
    • 宏替换不占运行时间,只占预处理时间。而函数调用则占运行时间(分配单元、保留现场、值传递、返回)。
    • 一般用宏来代表简短的表达式比较合适。有些问题,用宏和函数都可以。
    • 如果善于利用宏定义,可以实现程序的简化。

格式库:

  • 头文件,利用宏定义进行制作。
#include<stdio.h>
#define  PF   printf
#define  NL   \n
#define  D    %d  	//d后面有空格
#define  D1   D   NL      //输出一个整数并换行
#define  D4   D   D   D   D   NL   //输出四个整数并换行
//		   PF(%d  %d  %d  %d  \n,a,b,c);置换之后是这样的;
#define S  %s

�优点

猜你喜欢

转载自blog.csdn.net/weixin_41995541/article/details/89646055
今日推荐