打印
[51单片机]

收集C语言中8位机无符号整型跟两个无符号字符型互相转换的方法

[复制链接]
6403|27
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
寒舍|  楼主 | 2014-7-4 07:56 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
学生不才最近在做一小型操作系统,牵涉到地址链接计算,其中有16位地址需转换成两个8位地址分成两次发送。为计算方便并优化系统,现收集C语言中8位机无符号整型跟两个无符号字符型互相转换的方法。
方法一:
uint a;
uchar b,c;
//整型转字符型
b=a;//低8位
c=(a>>8);//高8位
//字符型转整型
a=c;
a<<=8;
a+=b;
方法二:
uint a;
uchar b,c;
//整型转字符型
b=a/256;//高位
c=a%256;//低位
//字符型转整型
a=b*256+c;

这是我自己想到的方法,请广大同仁朋友老师指教!如另有方法,不吝分享!

相关帖子

沙发
Leeone| | 2014-7-4 09:10 | 只看该作者
typedef union {
uint a;
u8 b;
u8 c;
} data;

使用特权

评论回复
评分
参与人数 1威望 +2 收起 理由
寒舍 + 2 赞一个!
板凳
原野之狼| | 2014-7-4 09:25 | 只看该作者
Leeone 发表于 2014-7-4 09:10
typedef union {
uint a;
u8 b;

赞!

使用特权

评论回复
地板
z755924843| | 2014-7-4 09:37 | 只看该作者
Leeone 发表于 2014-7-4 09:10
typedef union {
uint a;
u8 b;

不是很理解 怎么用啊?谢谢了

使用特权

评论回复
5
寒舍|  楼主 | 2014-7-4 09:38 | 只看该作者
Leeone 发表于 2014-7-4 09:10
typedef union {
uint a;
u8 b;

这只是个链表结构,不具备转换功能,倒可以跟我上面的例子结合,构成一个转换函数。

使用特权

评论回复
6
原野之狼| | 2014-7-4 09:42 | 只看该作者
把操作系统SHOW一下呗~

使用特权

评论回复
7
Leeone| | 2014-7-4 09:43 | 只看该作者
寒舍 发表于 2014-7-4 09:38
这只是个链表结构,不具备转换功能,倒可以跟我上面的例子结合,构成一个转换函数。 ...

你还想把它咋写成转换函数,写个看看

使用特权

评论回复
8
寒舍|  楼主 | 2014-7-4 10:07 | 只看该作者
Leeone 发表于 2014-7-4 09:43
你还想把它咋写成转换函数,写个看看

struct  tran{
uint a;
uchar b,c;
}data;
data.a=data.b*256+data.c;

使用特权

评论回复
9
Leeone| | 2014-7-4 10:11 | 只看该作者
寒舍 发表于 2014-7-4 10:07
struct  tran{
uint a;
uchar b,c;

是union 你把它搞成 struct 了,union也不是你那样用地

使用特权

评论回复
10
寒舍|  楼主 | 2014-7-4 10:21 | 只看该作者
原野之狼 发表于 2014-7-4 09:42
把操作系统SHOW一下呗~

是套带有人机界面覆盖本公司大部分产品的半自动测试系统,说是小型系统,但也挺庞大的。程序体二十几K。尚未完工,还不适合展示。。

使用特权

评论回复
11
原野之狼| | 2014-7-4 10:23 | 只看该作者
union直接取就是了,还转换啥呀。

使用特权

评论回复
12
李富贵| | 2014-7-4 10:30 | 只看该作者
union,还有一种更简单的强制指针类型转换,这两种做法都比撸主的方法快得多,但是缺点是有大小端问题,移植的时候会出问题。撸主的方法虽然慢但是不存在大小端问题,但是可能会有int长度不同的问题。此事古难全。。。

使用特权

评论回复
13
寒舍|  楼主 | 2014-7-4 10:36 | 只看该作者
Leeone 发表于 2014-7-4 10:11
是union 你把它搞成 struct 了,union也不是你那样用地

哦,使用共用体!这想法真是别出一格!回头加分!

使用特权

评论回复
14
寒舍|  楼主 | 2014-7-4 20:19 | 只看该作者
Leeone 发表于 2014-7-4 09:10
typedef union {
uint a;
u8 b;

为区分高8位低8位,还可以优化下
typedef union{
uint a;
uchar b[2];
}

使用特权

评论回复
15
roykin| | 2014-7-4 20:55 | 只看该作者
http://blog.csdn.net/firefly_2002/article/details/7954458
这里有链接 我看了 懂了呢。。原来8位也可以扩展为16位。。但是要是整型数据有符号的呢?

使用特权

评论回复
16
江枫渔火| | 2014-7-4 22:27 | 只看该作者
这也算个问题啊

使用特权

评论回复
17
Leeone| | 2014-7-4 23:10 | 只看该作者
寒舍 发表于 2014-7-4 20:19
为区分高8位低8位,还可以优化下
typedef union{
uint a;

数组也可以强制类型转换。总得来说大小端问题是要考虑的

使用特权

评论回复
18
lanmp| | 2014-7-5 00:34 | 只看该作者
#define HIGH(a) *((unsigned char)(&a))

使用特权

评论回复
19
hgjinwei| | 2014-7-5 07:09 | 只看该作者
这是鄙人使用多年的方法,见笑了。
/**
* __vat - 强制获取指定内存偏移数据
* @base   - 内存地址基址
* @offset - 地址偏移
*/
#ifndef __vat
#   define __vat(_base,_offset)         (((uint8*)(_base))[_offset])
#endif


/* 以大端格式读取16位数值   */
#define GET_BE_UINT16(pt)               ( ((uint16)__vat(pt,0) <<  8) \
                                        | ((uint8 )__vat(pt,1) <<  0) )

/* 以大端格式读取24位数值   */
#define GET_BE_UINT24(pt)               ( ((uint32)__vat(pt,0) << 16) \
                                        | ((uint16)__vat(pt,1) <<  8) \
                                        | ((uint8 )__vat(pt,2) <<  0) )

/* 以大端格式读取32位数值   */
#define GET_BE_UINT32(pt)               ( ((uint32)__vat(pt,0) << 24) \
                                        | ((uint32)__vat(pt,1) << 16) \
                                        | ((uint16)__vat(pt,2) <<  8) \
                                        | ((uint8 )__vat(pt,3) <<  0) )

/* 以大端格式读取64位数值   */
#define GET_BE_UINT64(pt)               ( ((uint64)__vat(pt,0) << 56) \
                                        | ((uint64)__vat(pt,1) << 48) \
                                        | ((uint64)__vat(pt,2) << 40) \
                                        | ((uint64)__vat(pt,3) << 32) \
                                        | ((uint32)__vat(pt,4) << 24) \
                                        | ((uint32)__vat(pt,5) << 16) \
                                        | ((uint16)__vat(pt,6) <<  8) \
                                        | ((uint8 )__vat(pt,7) <<  0) )

/* 以大端格式写16位数值     */
#define PUT_BE_UINT16(pt,val) \
do{ \
    __vat(pt,0) = (uint8)((uint16)(val) >>  8); \
    __vat(pt,1) = (uint8)((uint8 )(val) >>  0); \
}while(0)

/* 以大端格式写24位数值     */
#define PUT_BE_UINT24(pt,val) \
do{ \
    __vat(pt,0) = (uint8)((uint32)(val) >> 16); \
    __vat(pt,1) = (uint8)((uint16)(val) >>  8); \
    __vat(pt,2) = (uint8)((uint8 )(val) >>  0); \
}while(0)

/* 以大端格式写32位数值     */
#define PUT_BE_UINT32(pt,val) \
do{ \
    __vat(pt,0) = (uint8)((uint32)(val) >> 24); \
    __vat(pt,1) = (uint8)((uint32)(val) >> 16); \
    __vat(pt,2) = (uint8)((uint16)(val) >>  8); \
    __vat(pt,3) = (uint8)((uint8 )(val) >>  0); \
}while(0)

/* 以大端格式写64位数值     */
#define PUT_BE_UINT64(pt,val) \
do{ \
    __vat(pt,0) = (uint8)((uint64)(val) >> 56); \
    __vat(pt,1) = (uint8)((uint64)(val) >> 48); \
    __vat(pt,2) = (uint8)((uint64)(val) >> 40); \
    __vat(pt,3) = (uint8)((uint64)(val) >> 32); \
    __vat(pt,4) = (uint8)((uint32)(val) >> 24); \
    __vat(pt,5) = (uint8)((uint32)(val) >> 16); \
    __vat(pt,6) = (uint8)((uint16)(val) >>  8); \
    __vat(pt,7) = (uint8)((uint8 )(val) >>  0); \
}while(0)


/* 以小端格式读取16位数值   */
#define GET_LE_UINT16(pt)               ( ((uint8 )__vat(pt,0) <<  0) \
                                        | ((uint16)__vat(pt,1) <<  8) )

/* 以小端格式读取24位数值   */
#define GET_LE_UINT24(pt)               ( ((uint8 )__vat(pt,0) <<  0) \
                                        | ((uint16)__vat(pt,1) <<  8) \
                                        | ((uint32)__vat(pt,2) << 16) )

/* 以小端格式读取32位数值   */
#define GET_LE_UINT32(pt)               ( ((uint8 )__vat(pt,0) <<  0) \
                                        | ((uint16)__vat(pt,1) <<  8) \
                                        | ((uint32)__vat(pt,2) << 16) \
                                        | ((uint32)__vat(pt,3) << 24) )

/* 以小端格式读取64位数值   */
#define GET_LE_UINT64(pt)               ( ((uint8 )__vat(pt,0) <<  0) \
                                        | ((uint16)__vat(pt,1) <<  8) \
                                        | ((uint32)__vat(pt,2) << 16) \
                                        | ((uint32)__vat(pt,3) << 24) \
                                        | ((uint64)__vat(pt,4) << 32) \
                                        | ((uint64)__vat(pt,5) << 40) \
                                        | ((uint64)__vat(pt,6) << 48) \
                                        | ((uint64)__vat(pt,7) << 56) )

/* 以小端格式写16位数值     */
#define PUT_LE_UINT16(pt,val) \
do{ \
    __vat(pt,0) = (uint8)((uint8 )(val) >>  0); \
    __vat(pt,1) = (uint8)((uint16)(val) >>  8); \
}while(0)

/* 以小端格式写24位数值     */
#define PUT_LE_UINT24(pt,val) \
do{ \
    __vat(pt,0) = (uint8)((uint8 )(val) >>  0); \
    __vat(pt,1) = (uint8)((uint16)(val) >>  8); \
    __vat(pt,2) = (uint8)((uint32)(val) >> 16); \
}while(0)

/* 以小端格式写32位数值     */
#define PUT_LE_UINT32(pt,val) \
do{ \
    __vat(pt,0) = (uint8)((uint8 )(val) >>  0); \
    __vat(pt,1) = (uint8)((uint16)(val) >>  8); \
    __vat(pt,2) = (uint8)((uint32)(val) >> 16); \
    __vat(pt,3) = (uint8)((uint32)(val) >> 24); \
}while(0)

/* 以小端格式写64位数值     */
#define PUT_LE_UINT64(pt,val) \
do{ \
    __vat(pt,0) = (uint8)((uint8 )(val) >>  0); \
    __vat(pt,1) = (uint8)((uint16)(val) >>  8); \
    __vat(pt,2) = (uint8)((uint32)(val) >> 16); \
    __vat(pt,3) = (uint8)((uint32)(val) >> 24); \
    __vat(pt,4) = (uint8)((uint64)(val) >> 32); \
    __vat(pt,5) = (uint8)((uint64)(val) >> 40); \
    __vat(pt,6) = (uint8)((uint64)(val) >> 48); \
    __vat(pt,7) = (uint8)((uint64)(val) >> 56); \
}while(0)

使用特权

评论回复
评论
寒舍 2014-7-6 20:21 回复TA
费老半天功夫,终于看懂了。。用指针数组强制提取变量数据也算一种方法了。不知是否占资源,未检验。感谢分享! 
评分
参与人数 1威望 +1 收起 理由
寒舍 + 1
20
sxhhhjicbb| | 2014-7-5 12:36 | 只看该作者
感觉你这不叫“做一小型操作系统”,是在用吧。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

40

帖子

0

粉丝