C语言宏定义容易认不清的盲区梳理

目录
  • 1、概念
  • 3、宏不是函数
  • 4、宏定义不是说明或语句
  • 5、宏不是类型定义
  • 6、与之相关的宏定义
  • 7、总结

1、概念

#define命令是C语言中的一个宏定义命令,它用来将一个标识符定义为一个字符串,该标识符被称为宏名,被定义的字符串称为替换文本。

命令有两种格式:一种是简单的宏定义,另一种是带参数的宏定义。

(1)简单的宏定义:

#define<宏名> <字符串>

#defineVALUE((sizeof(a))/sizeof(a[0]))

(2) 带参数的宏定义

#define<宏名> (<参数表>)<宏体>

#defineMAX(a,b)((a)>(b)?(a):(b))

2、不能忽略宏定义中的空格

下面的宏定义中f是否带了参数呢?

#definef(x)((x)+1)

答案是否定的,在f与(x)之间存在一个空格,导致变成了如下定义。

#define f (x)((x)+1)

预处理程序对它不作任何检查。如有错误,只能在编译已被宏展开后的源程序时发现。

3、宏不是函数

如果我们定义一个宏:

#defineMAX(a,b)a>b?a:b

当我们执行一个语句:

3+MAX(1,3);

我们期望的答案应该是6才对,其实呢,运行之后的答案1。与宏定义相挂钩的就是优先级,算数运算符的优先级高于条件运算符,展开如下。

3+1>3?1:3,首先进行算符运算符的运算,即4>3?1:3,所以答案为1。

请注意宏定义中的括号,这些括号的作用就是预防引起优先级相关的问题。有些专家建议在C语言中只要牢记两个优先级就够了,乘除法优先级高于加减法,在设计其它操作符时,一律加上括号。

4、宏定义不是说明或语句

在行末不必加分号,如加上分号则连分号也一起置换

5、宏不是类型定义

首先定义一个宏

#definepCharchar*

再用pChar 定义两个变量,之后用操作符sizeof读取变量所占用内存大小,如果是指针类型的就占4个字节,如果是字符型的就占1个字节。

结果占用空间不一样,变量类型自然不一样,所以宏定义不是类型定义。那如果我换成typedef来定义类型呢?

宏定义只是简单的字符串代换,是在预处理完成的,而typedef是在编译时处理的,它不是作简单的代换,而是对类型说明符重新命名。被命名的标识符具有类型定义说明。

6、与之相关的宏定义

编写程序过程中,很多都需要条件编译,来看一个常用的使用方法。

#if defined(CREDIT)
    credit();
#elif defined(DEBIT)
    debit();
#else
    printerror();
#endif

7、总结

宏的本质是代码替换。

到此这篇关于C语言宏定义容易认不清的盲区梳理的文章就介绍到这了,更多相关C语言宏定义内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 一文带你搞懂C语言预处理宏定义

    目录 预定义符号 #define #define 定义标识符 #define 定义宏 替换规则 # 和## 预定义符号 这些预定义符号都是语言内置的 __FILE__ //进行编译的源文件 __LINE__ //文件当前的行号 __DATE__ //文件被编译的日期 __TIME__ //文件被编译的时间 __STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义 VS环境下未定义__STDC__ ,说明Visual Studio并未完全遵循ANSI C. #define #defi

  • C生万物C语言宏将整数二进制位的奇偶数位交换

    目录 题目分析 && 实现思路[位运算] 1.获取这个整数的奇数位和偶数位 2.使用移位运算使[奇变偶][偶变奇] 3.合并奇数位和偶数位 ⌨代码分析 1.代码展示 2.算法图解分析 总结与提炼 题目分析 && 实现思路[位运算] 首先来说一下本题的实现思路

  • C语言详细分析宏定义与预处理命令的应用

    目录 宏定义与预处理命令 预处理命令 - 宏定义 定义符号常量 定义傻瓜表达式 定义代码段 预定义的宏 函数 VS 宏定义 预处理命令 - 条件式编译 示例 宏定义与预处理命令 预处理阶段:处理宏定义与预处理命令: 编译期:检查代码,分析语法.语义等,最后生成.o或.obj文件: 链接期:链接所有的.o或.obj文件,生成可执行文件. 预处理命令 - 宏定义 定义符号常量 #define PI 3.1415926 #define MAX_N 10000 定义傻瓜表达式 #define MAX(a

  • C语言交换奇偶位与offsetof宏的实现方法

    目录 交换奇偶位 offsetof 宏 总结 交换奇偶位 题目内容:写一个宏,可以将一个整数的二进制位的奇数位和偶数位交换. 注:二进制补码的最低位为第一位,最高位为第三十二位. 示例 1:输入:10输出:5解释:10的二进制补码为00000000000000000000000000001010,交换奇偶位后为00000000000000000000000000000101,该二进制补码为5的二进制补码,故输出为5. 思路:交换奇偶位,其实就当于将偶数位右移了一位,奇数位左移了一位.那现在的问题

  • C语言宏定义的扩展定义讲解

    目录 1. 常量宏定义 2. 定义宏函数 3. 宏定义和#号结合 4. 宏定义和两个#结合 5. 宏定义和do…while()的结合 6. #ifdef…#else…#endif 7. #ifndef…#else…#endif 8. #if defined() … #else … #endif 1. 常量宏定义 使用c中的#define 来定义一个常量来表示一年有多少秒 #define SECONDS_PER_YEAR (606024*365)UL 求圆的周长: #define D® (r +

  • C语言#define定义宏的使用详解

    目录 1.宏是什么 2.宏的用法 3. 宏的注意事项 4. 宏和函数的区别 5.命名要求 6. 条件编译 常见条件编译指令及应用场景 1.宏是什么 #define 机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏(macro)或定义宏(define macro). 语法: #define name( parament-list ) stuff parament-list:是一个由逗号隔开的符号表. 2.宏的用法 #define SUM(x,y) ((x)+(y)) int main

  • C语言宏定义容易认不清的盲区梳理

    目录 1.概念 3.宏不是函数 4.宏定义不是说明或语句 5.宏不是类型定义 6.与之相关的宏定义 7.总结 1.概念 #define命令是C语言中的一个宏定义命令,它用来将一个标识符定义为一个字符串,该标识符被称为宏名,被定义的字符串称为替换文本. 命令有两种格式:一种是简单的宏定义,另一种是带参数的宏定义. (1)简单的宏定义: #define<宏名> <字符串> #defineVALUE((sizeof(a))/sizeof(a[0])) (2) 带参数的宏定义 #defin

  • C/C++语言宏定义使用实例详解

     C/C++语言宏定义使用实例详解 1. #ifndef 防止头文件重定义 在一个大的软件工程里面,可能会有多个文件同时包含一个头文件,当这些文件编译链接成 一个可执行文件时,就会出现大量"重定义"的错误.在头文件中实用#ifndef #define #endif能避免头文件的重定义. 方法:例如要编写头文件test.h 在头文件开头写上两行: #ifndef TEST_H #define TEST_H //一般是文件名的大写 头文件结尾写上一行: #endif 这样一个工程文件里同时

  • C语言宏定义#define的使用

    目录 无参宏定义 定义形式 带参宏定义 定义形式 #和##运算 #运算 用法: ##运算 用法: 变参宏 #ifndef 条件编译 宏定义是高级语言编译器提供的常用语法,其目的是利用某一标识符标识某个文本字符串.在编写程序时,如果程序中反复地使用某个数据或某段程序片段,就可以考虑将这个数据或程序片段定义为宏,然后每个出现该数据或程序片段的地方用宏名替代,选择宏定义来做的好处是程序简洁,可读性好,而且当需要修改这些相同的程序片段时,只要修改宏定义中的字符串即可,不需要修改多处. 宏定义命令:def

  • C语言宏定义使用分析

    1.如何区分宏定义中的"宏名称"和"宏字符串"?对于带参数的宏又该注意什么? 在宏定义中,"宏名称"和"宏字符串"是通过"空格"来区分的.编译器在处理时宏定义时,首先从"#define"后第一个空格开始读取字符串,直到遇见下一个空格为止,两个空格之间的字符串为"宏名称",确定好"宏名称"之后,本行的所有其他字符串都为"宏字符串"

  • C语言宏定义结合全局变量的方法实现单片机串口透传模式

    何谓透传? 根据百度百科给出的定义如下: 透传,即透明传输(pass-through),指的是在通讯中不管传输的业务内容如何,只负责将传输的内容由源地址传输到目的地址,而不对业务数据内容做任何改变. 在现实单片机产品开发过程中,如果存在多个串口,在调试打印某个模块信息的时候,大多数人的做法是将所有模块的TX.RX.GND引出来,分别接到不同的调试口去,通过PC终端去将这些信息分别打印出来.这样子做难免会弄错,甚至非常繁琐,万一不小心还会接错导致模块烧坏. 于是,透传模式的出现就是为了解决这样的问

  • C语言详细分析宏定义的使用

    目录 一.C语言中函数的“缺陷” 二.再次理解函数 三.C语言中的宏 四.宏与函数的不同 五.编译器组成简介 六.宏使用示例 七.再论宏常量 八.小结 一.C语言中函数的“缺陷” 实参和形参之间仅仅是值传递,因此,函数中无法直接改变实参. 二.再次理解函数 函数是一种代码复用的手段 把实现某个功能的代码片段进行封装(当作一个整体) 给这个代码片段一个合适的名字(通过名字使用代码) 定义参数(定义代码片段需要处理的问题) 三.C语言中的宏 宏是C语言中代码复用的补充方式 宏定义语法:#define

  • C语言中宏定义使用的小细节

    #pragma#pragma 预处理指令详解 在所有的预处理指令中,#Pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作.#pragma指令对每个编译器给出了一个方法,在保持与C和 C++语言完全兼容的情况下,给出主机或操作系统专有的特征.依据定义,编译指示是机器或操作系统专有的,且对于每个编译器都是不同的. 其格式一般为: #Pragma Para.............etc.. baike.baidu.com/view/1451188.htm

  • 详解C语言中的#define宏定义命令用法

    #define 命令#define定义了一个标识符及一个串.在源程序中每次遇到该标识符时,均以定义的串代换它.ANSI标准将标识符定义为宏名,将替换过程称为宏替换.命令的一般形式为: #define identifier string 注意: 1.该语句没有分号.在标识符和串之间可以有任意个空格,串一旦开始,仅由一新行结束. 2.宏名定义后,即可成为其它宏名定义中的一部分. 3.宏替换仅仅是以文本串代替宏标识符,前提是宏标识符必须独立的识别出来,否则不进行替换.例如: #define XYZ t

随机推荐