define可变参数

一般在调试打印Debug信息的时候, 需要可变参数的宏. 从C99开始可以使编译器标准支持可变参数宏(variadic macros), 另外GCC也支持可变参数宏, 但是两种在细节上可能存在区别.

1. __VA_ARGS__

/*__VA_ARGS__ 将 "..." 传递给宏 . 如*/

#define debug(format, ...) fprintf(stderr, format, __VA_ARGS__)

2. GCC的复杂宏

/*GCC使用一种不同的语法,从而可以给可变参数一个名字,如同其它参数一样.*/

#define debug(format, args...) fprintf (stderr, format, args)

/* 这和第一条的宏例子是完全一样的,但是这么写可读性更强并且更容易进行描述. */

3. ##__VA_ARGS__

/* 上面两个定义的宏,如果出现 debug("A Message")的时候,由于宏展开后有个多余的逗号,所以将导致编译错误.为了解决这个问题,CPP 使用一个特殊的"##"操作,格式如下:  */

#define debug(format, ...) fprintf (stderr, format, ## __VA_ARGS__)

/* 这里,如果可变参数被忽略或为空,"##"操作将使预处理器(preprocessor)去除掉它前面的那个逗号. */

2 float类型数据的传输

/* float型数据直接按照int型类似的发送肯定是不行的,这就需要采用指针的方法:*/

void float_char(float f,unsigned char *s)

{

unsigned char *p;

p = (unsigned char *)&f;

*s = *p;

*(s+1) = *(p+1);

*(s+2) = *(p+2);

*(s+3) = *(p+3);

}

/* 通过这种方法把数组s发送出去,在接受端接受到的就是标准的IEEE754结构的原始数据,也就是float型数据在内存中存放的值,如果需要得到这个float型数据的值还需要进行一个转换。

这种方法比较简单明了,这时候的串口接收端可以用现成的,不需要自己编写。 */

/*还可以采用共用体的方法,如果采用共用体时串口的接收端软件需要自己编写。我们知道共用体可以使不同的数据类型来共享相同的地址空间,所以程序如下:*/

void float_char(float f,unsigned char *s)

{

union change  {

float d;

unsigned char dat[4];

} r1;

r1.d = f;

*s = r1.dat[0];

*(s+1) = r1.dat[1];

*(s+2) = r1.dat[2];

*(s+3) = r1.dat[3];

}

/* 接收端采用同样的程序编写就可以得到float型数据的值了,不再需要其他的转换。 */

/* 类似的,传输long型或int型时也可以采用共用体的方法: */

void long_char(unsigned long l,unsigned char *s)

{

union change {

long d;

unsigned char dat[4];

}r1;

r1.d = l;

*s = r1.dat[0];

*(s+1) = r1.dat[1];

*(s+2) = r1.dat[2];

*(s+3) = r1.dat[3];

}

/*同时还有内存操作函数/调用库函数的方法,但这种方法对编译器要求过高*/

define可变参数,float数据传输的更多相关文章

  1. volatile,可变参数,memset,内联函数,宽字符窄字符,国际化,条件编译,预处理命令,define中##和#的区别,文件缓冲,位域

    1.volatile: 要求参数修改每次都从内存中的读取.这种情况要比普通运行的变量需要的时间长. 当设置了成按照C99标准运行之后,使用volatile变量之后的程序运行的时间将比register的 ...

  2. C语言可变参数函数实现原理

    一.可变参数函数实现原理 C函数调用的栈结构: 可变参数函数的实现与函数调用的栈结构密切相关,正常情况下C的函数参数入栈规则为__stdcall, 它是从右到左的,即函数中的最右边的参数最先入栈. 本 ...

  3. C语言 可变参数

    一.基础部分 1.1 什么是可变长参数 可变长参数:顾名思义,就是函数的参数长度(数量)是可变的.比如 C 语言的 printf 系列的(格式化输入输出等)函数,都是参数可变的.下面是 printf ...

  4. 【转载】va_list 可变参数 简介 va_copy vprintf

    [说明]本文转载自 smart 的文章 http://blog.sina.com.cn/s/blog_590be5290100qhxr.html  及百度百科 va_list是一个宏,由va_star ...

  5. C语言的可变参数

    可变参数给编程带来了很大的方便,在享受它带来的方便的同时,很有必要了解一下其实现方式,在了解编程语言的同时,也可以扩展编程的思路. 可变参数需要用到3个宏函数和一个类型,他们都定义在<stdar ...

  6. 利用可变参数模拟Printf()函数实现一个my_print()函数和调用可变参数注意的陷阱!

    可变参数函数的实现与函数调用的栈结构密切相关,正常情况下C的函数参数入栈规则为__stdcall, 它是从右到左的,即函数中的最右边的参数最先入栈. 例如,对于函数: void test(char a ...

  7. 可变参数模拟printf()函数实现一个my_print()函数以及调用可变参数需注意的陷阱

    入栈规则 可变参数函数的实现与函数调用的栈帧结构是密切相关的.所以在我们实现可变参数之前,先得搞清楚 栈是怎样传参的. 正常情况下,C的函数参数入栈遵照__stdcall规则, 它是从右到左的,即函数 ...

  8. 在C/C++函数中使用可变参数

    原文链接地址:http://blog.csdn.net/djinglan/article/details/8425768 下面介绍在C/C++里面使用的可变参数函数. 先说明可变参数是什么,先回顾一下 ...

  9. va_list可变参数

    可变参数函数实现 va_list,va_start,va_arg,va_end va可变参数意思,variable-argument. 1. 头文件及实现 linux中定义在gcc头文件中,stdar ...

随机推荐

  1. 「SDOI2005」区间

    「SDOI2005」区间 传送门 记录每一个位置作为左端点和右端点的出现次数,然后直接考虑差分即可. 参考代码: #include <cstdio> #define rg register ...

  2. Python开发:变量类型

    1.变量赋值 #!/usr/bin/python # -*- coding: UTF-8 -*- counter = 100 # 赋值整型变量 miles = 1000.0 # 浮点型 name = ...

  3. 如何去掉Eclipse注释中英文单词的拼写错误检查

  4. (未解决)flume监控目录,抓取文件内容推送给kafka,报错

    flume监控目录,抓取文件内容推送给kafka,报错: /export/datas/destFile/220104_YT1013_8c5f13f33c299316c6720cc51f94f7a0_2 ...

  5. xcode app 在iOS13.3.1上崩掉

    问题背景: 以前搞的一个项目,昨天测试还好的,今天就无法在iphone上运行了,对比了一下昨天是13.3,今天是13.3.1 其它的没有区别,只要运行就崩,根本没有办法启动. 报错提示: dyld: ...

  6. Android游戏开发学习(5)--实现Button悬浮于与SurfaceView之上

    原文:http://daikainan.iteye.com/blog/1407355 实现Button悬浮于与SurfaceView之上实现 先看效果: 注意:你实现的SurfaceView和andr ...

  7. AWS-DDNS

    1. DDNS 2. 在 Linux 实例上设置动态 DNS 2.1 Ubuntu 2.2 Amazon Linux 2 2.3 Arch Linux 2.4 其他Linux系统 3. 更多相关 1. ...

  8. uniGUI之MainModule(12)

    1]必须设置.  一个 user 一个, 在此放数据库控件是各 user 独立 2]常用属性: 应用 MainModule 正确的方法是将连接组件放置在 MainModule 上, 并将数据集放在窗体 ...

  9. JavaScript 的数据类型

    一.分类 根据 JavaScript 中的变量类型传递方式,分为基本数据类型和引用数据类型.其中基本数据类型包括Undefined.Null.Boolean.Number.String.Symbol ...

  10. 代理实现aop以及代理工厂实现增强

    一.静态代理实现 1.接口(抽象主题) 2.接口的实现类(真实主题) 3.代理类(代理主题) 4.测试类: ApplicationContext context=new ClassPathXmlApp ...