C语言宏定义讲解

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

摘要

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

不带参数的宏定义:

  • 用一个指定的标识符(即名字)来代表一个字符串。
#define 标识符 字符串 //标识符会被字符串所替代 //eg:定义符号常量#define PI 3. 
  • 作用:
    • 在本程序文件中用指定的标识符PI来代替”3.”这个字符串。在进行预处理时,将程序中凡是在该指令以后出现的所有的”P”都用”3.”代替。这种方法使用户能以一个简单的名字代替一个长的字符串,因此把这个标识符(名字)称为“宏名”,在预处理时将宏名替换成字符串的过程称为“宏展开”。 #define就是宏定义指令。一改全改
  • 说明:
    1. 宏定义只是用宏名代替一个字符串,也就是只作简单的置换,不作正确性检查。如果写成#define PI 3. 即把数字 1 错写成小写字母 1,在预处理时也照样把字母 l 代入,不管是否符合用户原意,也不管含义是否有意义。预处理时不作任何语法检查。只有对已被宏展开后的源程序进行编译时才会发现语法错误并报错。
    2. 宏定义不是C语句,不必在行末加分号。如果加了分号则会连分号一起进行置换。
      //eg: #define PI 3.; area=PI*r*r; area=3.;*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 
     #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 

�优点

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/207880.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 下午12:52
下一篇 2026年3月19日 下午12:53


相关推荐

  • 小树311_森林小道

    小树311_森林小道原题链接森森开了一家快递公司,叫森森快递。因为公司刚刚开张,所以业务路线很简单,可以认为是一条直线上的N个城市,这些城市从左到右依次从0到(N−1)编号。由于道路限制,第i号城市(i=0,⋯,N−2)与第(i+1)号城市中间往返的运输货物重量在同一时刻不能超过C​i​​ 公斤。公司开张后很快接到了Q张订单,其中j张订单描述了某些指定的货物要从S​j​​ 号城市运输到T​j​​ 号城市。这里我们简单地假设所有货物都有无限货源,森森会不定时地挑选其中一部分货物进行运输。安全起见,这些货物不会在中

    2022年8月9日
    6
  • 百度文心一言是什么意思

    百度文心一言是什么意思

    2026年3月12日
    2
  • Linux系统结构详解

    Linux系统结构详解Linux系统一般有4个主要部分:内核、shell、文件系统和应用程序。内核、shell和文件系统一起形成了基本的操作系统结构,它们使得用户可以运行程序、管理文件并使用系统。部分层次结构如图1-1所示。1.linux内核Linux内核是世界上最大的开源项目之一,内核是与计算机硬件接口的易替换软件的最低级别。它负责将所有以“用户模式”运行的应用程…

    2022年5月25日
    42
  • 百度發表Ernie X1以與DeepSeek R1競爭

    百度發表Ernie X1以與DeepSeek R1競爭

    2026年3月12日
    2
  • Enterprise Library 验证的实现

    Enterprise Library 验证的实现参考地址:http://www.cnblogs.com/huangcong/archive/2010/06/03/1749634.htmlEnterpriseLibrary的验证我觉得最大的改变了验证的位置,可以通过配置文件来修改验证规则,这就极大的使验证更加灵活,原文中的一个错误就是第一步让点击 AddDatabaseSettings这个地方错了,应该点击AddSecuritySe…

    2022年10月20日
    7
  • Vue-cli3 项目在安卓低版本系统和 IE 上白屏问题解决

    Vue-cli3 项目在安卓低版本系统和 IE 上白屏问题解决

    2021年7月4日
    112

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号