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()
{
    int a = 10;
    int b = 20;
    int ret = SUM(a, b);
    printf("%d\n", ret);
    return 0;
}

简要说明:宏已经被替换

分位三个阶段:预编译、编译、汇编

3. 宏的注意事项

定义什么替换什么

来看这一例:

#define NUM(x,y) x+y
int main()
{
    int a = 2;
    int b = 3;
    printf("%d\n", NUM(a, b) * NUM(a, b));
    //结果:11
    return 0;
}

原因:num(a,b)*num(a,b) = a + b * a + b=11

4. 宏和函数的区别

属性 #define定义宏 函数
代码长度 如果多次调用,多次替换,如果是大长度宏其长度很长 函数只实现一次可以多次使用,如果多次调用,长度只有一份
执行速度 更快 函数调用和开辟都会有额外开销
操作符优先级 必须每个参数加上括号,否则操作符优先级可能会产生不可预料的后果 函数参数只在函数调用的时候求值一次,它的结果值传递给函数。表达式的求值结果更容易预测
带有副作用参数 多次调用宏会有不可预料的后果 函数参数只在传参的时候求值一次,结果更容易控制,只需关注是传值还是传址
参数类型 宏的参数和类型无关,可以使用与任何参数类型 函数参数与类型有关,类型取决于使用目的,传值,传址,还是拿一个字节数据char*
调试 不方便调试,编译期间就已经替换 可调试
递归 不可递归 可递归

宏带副作用参数:

#define MAX(a, b) ( (a) > (b) ? (a) : (b) )
int main()
{
    int x = 5;
    int y = 8;
    int z = MAX(x++, y++);
    printf("x=%d y=%d z=%d\n", x, y, z);//输出的结果是什么
    return 0;
}
//( (x++) > (y++) ? (x++):(y++) )
//输出结果:x=6,y=10,z=9

5.命名要求

宏名必须大写

函数不要全部大写

6. 条件编译

常见条件编译指令及应用场景

1.单分支

编译指令:

#if 常量表达式
​ //…
#endif

应用场景:

int main()
{
#if 4>2
    printf("hello world!\n");
#endif
    return 0;
}
//输出hello world

2.多分支

编译指令:

#if 常量表达式
​ //…
#elif 常量表达式
​ //…
#else
​ //…
#endif

应用场景:

int main()
{
#if 1>2
    printf("xixi\n");
#elif 4>3
    printf("haha\n");
#else
    printf("heihei\n");
#endif
    return 0;
}
//输出结果:haha

可不能和if else选择语句混淆,多分支条件编译从上往下走,如果有一个分支成立,后面分支就不再执行;但是选择语句是从上往下走,有一个分支成立,继续查看后面分支是否成立

3.判断是否被定义

编译指令:

1. > #if defined(symbol) 或 #ifdef symbol

2. > #if !defined(symbol) 或 #ifndef symbol

应用场景:

  ```c

  #define DEF
  int main()
  {
  #if defined(DEF)
      printf("haha\n");
  #endif

  #ifdef MAX
      printf("heihei\n");
  #endif
      return 0;
  }
  //输出结果:haha
  ```

4.嵌套指令

编译指令

#if 常量表达式
#ifdef symbol
//操作
#endif
#elif 常量表达式
#ifdef symbol
//操作
#endif
#endif

条件编译指令也支持嵌套,注意#endif结束本次嵌套

5.删除宏定义

编译指令:

#undef

应用场景:

#define DEF
int main()
{
#undef DEF//删除DEF宏定义了
#ifdef DEF
    printf("hehe\n");
#endif
    return 0;
} 

以上就是C语言#define定义宏的使用详解的详细内容,更多关于C语言#define定义宏的资料请关注我们其它相关文章!

(0)

相关推荐

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

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

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

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

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

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

  • 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语言交换奇偶位与offsetof宏的实现方法

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

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

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

  • 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语言#define预处理宏定义

    目录 #define介绍: #define宏定义无参的一般形式为:#define  标识符 常量 #define宏定义有参的一般形式为:#define  标识符(参数表) 表达式 #运算符: ##运算符: 可变宏...和__VA_ARGS__: 开发项目中常用的宏定义: #define介绍: C语言里可以用#define定义一个标识符来表示一个常量.特点是:定义的标识符不占内存,只是一个临时的符号,预编译后这个符号就不存在了,也不做类型定义.预编译又叫预处理.预编译就是编译前的处理.这个操作是在

  • C语言#define拼接宏定义实现方式

    使用场合:拼接两个宏,一个是传入的宏.但是传入的宏不会被替换,反而原封不动的接了上去,这就尴尬了.经过各种尝试,居然成了,特此记录分享一下,方便大家学习. char A_param=0; char B_pramm=0; //添加宏定义 #define OBJECT A #define DEFINE_(X) X##_param //一次定义 #define DEFINE(X) DEFINE_(X) //再次定义 #define PARAM DEFINE(OBJECT) void fun() { /

  • C语言中强制地址跳转详解

    C语言中强制地址跳转详解 #define jump(TargetAddr ) (*((void(*)())(TargetAddr))() 第一个(( void( * )(  )) ,意思为强制类型转换为一个无形参,无返回值的函数指针,(*(TargetAddr))为跳转地址,但是函数指针变量不能为常数所以要加((void( * )(  )) 进行强制类型转换.最后一个()为执行的意思. 整一条指定的目的是为了跳转到一个绝对地址执行函数. 1.在单片机中可以实现软件复位,比如跳转到0地址. 2.如

  • C语言ASM汇编内嵌语法详解

    3 GCC Inline ASM GCC 支持在C/C++代码中嵌入汇编代码,这些汇编代码被称作GCC Inline ASM--GCC内联汇编.这是一个非常有用的功能,有利于我们将一些C/C++语法无法表达的指令直接潜入C/C++代码中,另外也允许我们直接写 C/C++代码中使用汇编编写简洁高效的代码. 1.基本内联汇编 GCC中基本的内联汇编非常易懂,我们先来看两个简单的例子: __asm__("movl %esp,%eax"); // 看起来很熟悉吧! 或者是 __asm__(&q

  • C语言 指针的初始化赋值案例详解

    目录 1.指针的初始化 2.指针的赋值 3.指针常量 4.指针初始化补充 5.void *型指针 6.指向指针的指针 1.指针的初始化 指针初始化时,"="的右操作数必须为内存中数据的地址,不能够是变量,也不能够直接用整型地址值(可是int*p=0;除外,该语句表示指针为空).此时,*p仅仅是表示定义的是个指针变量,并没有间接取值的意思. 比如: int a = 25; int *ptr = &a; int b[10]; int *point = b; int *p = &am

  • C语言 module_init函数与initcall案例详解

    module_init这个函数对做驱动的人来说肯定很熟悉,这篇文章用来跟一下这个函数的实现. 在include/linux/init.h里面有module_init的定义,自然,因为一个module可以在内核启动时自动加载进内核,也可以由我们手动在需要时加载进内核,基于这种场景,内核使用了MODULE这个宏,见代码: #ifndef MODULE #ifndef __ASSEMBLY__ ... #define __define_initcall(level,fn,id) \ static in

  • c语言的程序环境与预处理详解

    目录 1.翻译环境 2.运行环境 3.预处理详解 3.1#define定义的符号 3.2#define定义的宏 3.3#define的替换规则 3.4#与## 4.宏与函数对比 5.#undef 6.条件编译 7.文件包含 总结 c语言代码的实现包含两种环境 1.翻译环境,将源代码转化成可执行的机器指令 2.执行环境,执行代码 1.翻译环境 包括两个过程,编译与链接·程序中每一个源文件通过编译器转化成目标文件(obj)·这些目标文件又通过链接器捆绑在一起·链接器同时会链接标准库中的函数以及程序员

  • C语言实现“幸运数”的实例详解

    C语言实现"幸运数"的实例详解 1.题目: 标题:幸运数 幸运数是波兰数学家乌拉姆命名的.它采用与生成素数类似的"筛法"生成. 首先从1开始写出自然数1,2,3,4,5,6,-. 1 就是第一个幸运数. 我们从2这个数开始.把所有序号能被2整除的项删除,变为: 1 _ 3 _ 5 _ 7 _ 9 -. 把它们缩紧,重新记序,为: 1 3 5 7 9 -. .这时,3为第2个幸运数,然后把所有能被3整除的序号位置的数删去.注意,是序号位置,不是那个数本身能否被3整除!

  • C语言中的正则表达式使用示例详解

    正则表达式,又称正规表示法.常规表示法(英语:Regular Expression,在代码中常简写为regex.regexp或RE).正则表达式是使用单个字符串来描述.匹配一系列符合某个句法规则的字符串. 在c语言中,用regcomp.regexec.regfree 和regerror处理正则表达式.处理正则表达式分三步: 编译正则表达式,regcomp: 匹配正则表达式,regexec: 释放正则表达式,regfree. 函数原型 /* 函数说明:Regcomp将正则表达式字符串regex编译

随机推荐