C语言中#define在多行宏定义出错的原因及分析

目录
  • C语言中#define在多行宏定义出错的原因
    • 1.第一种错误
    • 2.第二种错误
  • 使用#define宏定义的几个小技巧
    • 1.调试开关
    • 2.条件编译
    • 3.宏实现函数
    • 4.跨行宏定义
    • 5.防止头文件被重复包含
    • 6.带参宏与带参函数的区别
    • 7.注意事项
  • 总结

C语言中#define在多行宏定义出错的原因

1.第一种错误

#include<stdio.h>
#define echange(a,b) {\/*宏定义中允许包含多行命令的情形,此时必须在最右边加上"\"*/
 int t;\
 t=a;\
 a=b;\
 b=t;\
}
main()
{
 int c, d;
 c = 2;
 d = 3;
 printf("%d %d\n", c, d);
 echange(c,d)
 printf("%d %d\n", c, d);
 return 0;
}

在用#define进行多行宏定义时,注释要放在"\"之前

2.第二种错误

#include<stdio.h>
#define echange(a,b) {/*宏定义中允许包含两道衣裳命令的情形,此时必须在最右边加上"\"*/\
 int t;\
 t=a;\
 a=b;\
 b=t;\
}/*在最后一行多加了一个"\"*/\
main()
{
 int c, d;
 c = 2;
 d = 3;
 printf("%d %d\n", c, d);
 echange(c,d)
 printf("%d %d\n", c, d);
 return 0;
}

在用#define进行多行宏定义时,在最后一行加上"\“,我们使用#define进行多行定义时,默认最后一个”\“的下一行也属于宏定义范围,去掉最后一行的”\"即可

以下是代码的正确形式

#include<stdio.h>
#define echange(a,b) {/*宏定义中允许包含两道衣裳命令的情形,此时必须在最右边加上"\"*/\
 int t;\
 t=a;\
 a=b;\
 b=t;\
}
main()
{
 int c, d;
 c = 2;
 d = 3;
 printf("%d %d\n", c, d);
 echange(c,d)
 printf("%d %d\n", c, d);
 return 0;
}

使用#define宏定义的几个小技巧

1.调试开关

有时候编写程序时为方便查找错误,会在很多地方加上串口打印语句直观查看程序哪里出错。

但是,串口的输出是需要时间的,在项目基本完成时,就需要将这些打印关闭,但是一行一行的注释掉费时费力,不现实。

这时可以使用宏来当做一个"开关",直接操作这个宏就可以实现打印的开关,例如:

//#define    DEBUG(...)
#define        DEBUG    printf

另外,还可以使用几个预定义的宏进行辅助:

__FILE__            // 文件
__FUNCTION__        // 函数
__LINE__            // 行号

DEBUG("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);

2.条件编译

当程序为了适配更多不同的环境时,还可以使用条件宏来选择不同的代码模块:

#if 1
    printf("Hello!\n");
#else
    printf("Hi!\n");
#endif

3.宏实现函数

交换两个数:

#define swap(a,b)     ((a)=(a)+(b);(b)=(a)-(b);(a)=(a)-(b))

比较两个数并且返回最小的数:

#define MIN(a,b)     ((a)<(b)?(a):(b))

求数组元素个数:

#define LENGTH(array)    (sizeof(array) / sizeof(array[0]))

4.跨行宏定义

#define    SWAP(a,b)    do { \
                        int t = 0;\
                        t = a; \
                        a = b; \
                        b = t; \
                    } while(0)

细心的你可能已经注意到以上宏末尾都没有带分号“;”

5.防止头文件被重复包含

#ifndef __TEST_H 
#define __TEST_H 
    // 头文件内容 
#endif

6.带参宏与带参函数的区别

  • 1.宏会在编译器在对源代码进行编译的时候进行简单替换,不会进行任何逻辑检测,即简单代码复制而已;
  • 2.宏进行定义时不会考虑参数的类型;
  • 3.参数宏的使用会使具有同一作用的代码块在目标文件中存在多个副本,即会增长目标文件的大小;
  • 4.参数宏的运行速度会比函数快,因为不需要参数压栈/出栈操作;
  • 5.参数宏在定义时要多加小心,多加括号;
  • 6.函数只在目标文件中存在一处,比较节省程序空间;
  • 7.函数的调用会牵扯到参数的传递,压栈/出栈操作,速度相对较慢;
  • 8.函数的参数存在传值和传地址(指针)的问题,参数宏不存在;

7.注意事项

  • 1.宏定义不会对引号内的参数进行替换;
  • 2.若要替换,可以在参数前面加上’#’转换成“字符串”,如:
#define dprint(expr) printf(#expr " = %d\n", expr)

使用dprint(x/y)就被替换成:

printf("x/y" " = %g\n", x/y);

printf("x/y = %g\n", x/y);

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

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

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

  • C语言中宏定义的妙用方法

    最近看了intel在linux内核中的驱动,学习到了一个非常有用的小技巧,如下代码: #define IN #define OUT #define UAdress volatile unsigned int * #define Raw_buffer void * void SetHwiPortsDataReg(IN UAdress Register , IN int value) { _SetHwiPortsDataReg(Register,&value); } void _Out_Put_va

  • C语言宏定义使用分析

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

  • C语言中#define在多行宏定义出错的原因及分析

    目录 C语言中#define在多行宏定义出错的原因 1.第一种错误 2.第二种错误 使用#define宏定义的几个小技巧 1.调试开关 2.条件编译 3.宏实现函数 4.跨行宏定义 5.防止头文件被重复包含 6.带参宏与带参函数的区别 7.注意事项 总结 C语言中#define在多行宏定义出错的原因 1.第一种错误 #include<stdio.h> #define echange(a,b) {\/*宏定义中允许包含多行命令的情形,此时必须在最右边加上"\"*/  int

  • C语言中#define定义的标识符和宏实例代码

    目录 1.#define定义标识符 语法 举个栗子 2.#define定义宏 #define替换的规则 #与###的用法: 宏的缺点 宏和函数的优缺点 总结 1.#define定义标识符 在C语言程序中,有时候会包含#define #define可以定义标识符 也就是说可以对字符重新定义,实现代替的作用 语法 #define  name  stuff 就比如说: #define MAX 1000(用MAX代替1000) #define reg   register (用reg代替register

  • C语言中#define预处理语法总结

    目录 一.使用#define定义标识符常量 语法1: 语法2: 二.#define来定义带有参数的宏 三.C语言给我们定义好的一些标识符常量 一.使用#define定义标识符常量 语法1: #define MAX 100 注意使用#define末尾不需要带; MAX是一个常量,是使用#define定义的一个标识符常量 !!! 我为什么要在这里强调这是一个常量呢?因为它和普通常量一样不可被修改 大家可能会疑惑使用const修饰的变量不也是不可被修改的吗,这两者有什么不同呢? 这里要强调一下,使用c

  • 浅谈关于C语言中#define的副作用

    MFC虽然没有未来,但是我觉得MFC的思想还是有必要研究研究的,在MFC中或者一些底层代码的编写中,宏是相当好用的,为什么呢?因为宏只是简单的替换,不进行类型转换,替换就意味着灵活,而C语言编程的灵魂就是灵活啊. 但是在高级语言中,甚至C++中,是提倡用const的,不提倡用#define,因为#define有一定的副作用,玩不好就没命了. 这里我们讨论下#define的副作用. # include <stdio.h> # include <stdlib.h> # define C

  • C语言中#define与typedef的互换细节详解

    复制代码 代码如下: #include <stdio.h>/*<---------           #define    string    char *            ---->*/typedef   char *   string; int main(void){   string   a[] = {"I", "like", "to", "fight,"},   b[] = {"

  • 深入聊聊C语言中的Const关键字

    目录 前言 01const简述 02常量的应用 常量作为函数的参数 C++中应用加const 03#define和const 总结 前言 const是一个C语言的关键字,它限定一个变量不允许被改变.使用const在一定程序上可以提高程序的健壮性,另外,在观看别人代码的时候,清晰理解const所起的作用,对理解别人的程序有所帮助. 01const简述 下面简单描述一下const,基本都是教科书的知识.const修饰的变量,其值存放在只读数据段中,其值不能被改变.称为只读变量.关于什么是数据段,什么

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

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

  • 详解C语言中typedef和#define的用法与区别

    目录 一.typedef的用法 二.#define的用法 三.typedef与#define的区别 四.typedef的用途 用途一 用途二 用途三 用途四 五.typedef的陷阱 陷阱一 陷阱二 一.typedef的用法 在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程的一部分,但它并不实际分配内存空间,比如: typedef int INT; typedef (int*) pINT; typedef unsigned int uint32_t type

  • C语言中typedef的用法以及#define区别详解

    目录 1.简洁定义 2.为已有类型起别名 为字符数组起别名 为指针起别名 3.typedef 和 #define 的区别 总结 1.简洁定义 C语言允许为一个数据类型起一个新的别名,就像给人起"绰号"一样.而编程中起别名,是为了编程人员编程方便,例如: 定义如下结构体 struct stu { int ID; char name[20]; float score[3]; char *data; }; 要想定义一个结构体变量就得这样写: struct stu Marry://Marry是

  • C语言中main函数与命令行参数详细讲解

    目录 一.main 函数的概念 二.main 函数的本质 命令行 三.main 函数的参数 四.main 函数一定是程序执行的第一个函数吗 五.小结 一.main 函数的概念 C语言中 main 函数称之为主函数 一个C程序是从 main 函数开始执行的 二.main 函数的本质 main 函数是操作系统调用的函数 操作系统总是将 main 函数作为应用程序的开始 操作系统将 main 函数的返回值作为程序的退出状态 下面看一下 main 函数的返回值: A.c: #include <stdio

随机推荐