[技巧]C语言中用结构体方式访问数组的方法
有时,你可能有一段内存,即需要用结构体的方式访问,又需要用数组的方式访问,通常情况可以用union,但使用时需要多打些字母
这里我给出一种技巧,可以使程序看起来简洁直观明了
比如定义一个串口发送的结构,缓冲区是256字体,并环形利用
typedef unsigned char u8
typedef u8 bool
===============================
typedef struct
{
bool IsOpen;
u8 CurPos;
u8 EndPos;
u8 Buffer;
} T_USART_WRITE;
typedef struct
{
u8 Status;
u8 TimeOut;
bool IsNew;
T_USART_WRITE Write;
T_USART_READ Read;
} T_USART_COMM;
extern T_USART_COMMComm;
可是当你停止使用USART时,这256字节不就浪费了吗...
移去做别的用时,只能按照字节访问,想必也会很不爽吧...
但有了宏就没问题了,比如
===============================================
typedef struct
{
u16 Address;
u8Code;
u8Check;
} T_REMOTE;
#define Remote *(T_REMOTE*)Comm.Write.Buffer
或
#define Remote *(T_REMOTE*)&Comm.Write.Buffer
================================================
此时当USART功能停止使用后,这256字节就完全释放出来了....
当作这种技巧的作用还有很多,比如按字节接收数据,但按照结构体来读取使用,等等...
就不一一列出来了... 下面没看明白,局部变量?
你说的这些一般是用堆分配内存再处理的吧? 不错,指向结构体的指针,强制类型转换。 留待观察 首先要知道typedef,就不多说
#define Remote *(T_REMOTE*)Comm.Write.Buffer
(T_REMOTE*)是强制类型转换
将Comm.Write.Buffer地址转换为结构体指针
====================================================
可以用Remote.Code或Remote.Address来操作所指向内存了
只要Comm定义时是全局变量,编译器编译后是绝对地址,没有任何效率问题... 在c++中,这种用法的优势,被“引用”所取代... 学习了!!
MARK 地址绑定……
我一般用一个宏来处理
#define TYPE_CONVERSION(__ADDR,__TYPE) (*(__TYPE *)(__ADDR))
以楼主的应用为例:
TYPE_CONVERSION(Comm.Write.Buffer,T_REMOTE)
不过我不是太推荐这种使用方法…… "union不能在struct内部使用"
毫无根据,此结论从何而来?????
http://cache.amobbs.com/bbs_upload782111/files_13/ourdev_426053.JPG
(原文件名:Image0251.JPG) 原来是这个东东,第一次用时就碰到字节对齐问题。。。。。 MARK 留待观察 我也在用
struct DownPkt
{
unsigned intAddr
unsigned char command;
union {
unsigned int Int;
unsigned char ch;
} Dat;
unsigned char ETX;
}down;
unsigned char *IBuf;
IBuf=(unsigned char *)&down;
down.Addr就可以直接用了,向IBuf中写数就可以通过down.Addr直接用了 来个位域的用法。
#include "Stdio.h"
#include "Conio.h"
typedef union
{
struct
{
unsigned one:1;
unsigned two:2;
unsigned three:3;
}BITS;
unsigned char l;
}MY_TYPE;
int main(void)
{
/* 此处添加你自己的代码 */
MY_TYPE val;
MY_TYPE *ptr;
val.BITS.one=1;
val.BITS.two=2;
val.BITS.three=3;
printf("%x\n",val.BITS.one);
printf("%x\n",val.BITS.two);
printf("%x\n",val.BITS.three);
ptr=&val;
ptr->l=0x12abcdef;
printf("-------------------\n");
printf("%x\n",val.BITS.one);
printf("%x\n",val.BITS.two);
printf("%x\n",val.BITS.three);
printf("-------------------\n");
printf("%x\n",ptr->BITS.one);
printf("%x\n",ptr->BITS.two);
printf("%x\n",ptr->BITS.three);
printf("sizeof(val)=%d\n",sizeof(val));
getch();
return 0;
} 一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。
如果遇到总共16bit,然后划分位2bit,10bit,4bit三位。
是不是10bit要拆分位6bit + 2bit方式呢? 注意对齐就行了 typedef union
{
struct
{
unsigned one:1;
unsigned two:2;
unsigned three:3;
}BITS;
unsigned char l;
}MY_TYPE;
更喜欢用:
typedef union
{
struct
{
unsigned char one:1;
unsigned char two:2;
unsigned char three:3;
};
unsigned char l;
}MY_TYPE;
MY_TYPE val;
val.one
val.two
val.three
val.l 技巧 技巧!!技巧就是垃圾的代名词!!! 楼上说的有一定的道理。 mark mark 不错啊,太深奥了 mark mark mark MARK ! 学习 我还以为你说的是柔性数组的知识呢,原来不是啊 学习一下
页:
[1]