snoopyzz 发表于 2009-3-17 10:39:56

[技巧]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字节就完全释放出来了....
当作这种技巧的作用还有很多,比如按字节接收数据,但按照结构体来读取使用,等等...
就不一一列出来了...

xullin 发表于 2009-3-17 11:08:21

下面没看明白,局部变量?

你说的这些一般是用堆分配内存再处理的吧?

lcw_swust 发表于 2009-3-17 11:10:05

不错,指向结构体的指针,强制类型转换。

zcllom 发表于 2009-3-17 11:15:15

留待观察

snoopyzz 发表于 2009-3-17 11:15:27

首先要知道typedef,就不多说

#define Remote    *(T_REMOTE*)Comm.Write.Buffer

(T_REMOTE*)是强制类型转换
将Comm.Write.Buffer地址转换为结构体指针
====================================================
可以用Remote.Code或Remote.Address来操作所指向内存了


只要Comm定义时是全局变量,编译器编译后是绝对地址,没有任何效率问题...

snoopyzz 发表于 2009-3-17 11:17:23

在c++中,这种用法的优势,被“引用”所取代...

deepin 发表于 2009-3-17 11:58:30

学习了!!
MARK

Gorgon_Meducer 发表于 2009-3-17 12:02:22

地址绑定……
我一般用一个宏来处理

#define TYPE_CONVERSION(__ADDR,__TYPE)               (*(__TYPE *)(__ADDR))

以楼主的应用为例:

TYPE_CONVERSION(Comm.Write.Buffer,T_REMOTE)

不过我不是太推荐这种使用方法……

__stm32f100__ 发表于 2009-3-17 12:15:15

"union不能在struct内部使用"

毫无根据,此结论从何而来?????

http://cache.amobbs.com/bbs_upload782111/files_13/ourdev_426053.JPG
(原文件名:Image0251.JPG)

xullin 发表于 2009-3-17 12:24:24

原来是这个东东,第一次用时就碰到字节对齐问题。。。。。

ljgvictory 发表于 2009-3-17 14:23:55

MARK

ddcour 发表于 2009-3-17 22:42:44

留待观察

gtembeded 发表于 2009-3-23 23:58:59

我也在用
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直接用了

hahacomcn 发表于 2009-3-24 10:33:37

来个位域的用法。

#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;
}

hahacomcn 发表于 2009-3-24 12:00:57

一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。

如果遇到总共16bit,然后划分位2bit,10bit,4bit三位。
是不是10bit要拆分位6bit + 2bit方式呢?

xihacow 发表于 2009-3-24 16:13:02

注意对齐就行了

void_c 发表于 2009-3-24 16:44:06

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

unsv 发表于 2009-6-6 00:07:13

技巧 技巧!!技巧就是垃圾的代名词!!!

electrician 发表于 2009-6-6 09:44:00

楼上说的有一定的道理。

twd3621576 发表于 2010-8-10 23:15:22

mark

gyd0317 发表于 2010-10-6 09:36:26

mark

lieshi 发表于 2010-10-6 15:47:10

不错啊,太深奥了

bj-stm8 发表于 2010-10-6 16:37:20

mark

liangyurongde 发表于 2010-10-6 17:18:10

mark

ringan865 发表于 2010-10-6 19:17:38

mark

xurenhui 发表于 2014-8-15 23:08:13

MARK ! 学习

myxiaonia 发表于 2014-8-26 14:52:14

我还以为你说的是柔性数组的知识呢,原来不是啊

chengying 发表于 2015-7-23 09:48:42

学习一下
页: [1]
查看完整版本: [技巧]C语言中用结构体方式访问数组的方法