搜索
bottom↓
回复: 27

[技巧]C语言中用结构体方式访问数组的方法

[复制链接]

出0入0汤圆

发表于 2009-3-17 10:39:56 | 显示全部楼层 |阅读模式
有时,你可能有一段内存,即需要用结构体的方式访问,又需要用数组的方式访问,
通常情况可以用union,但使用时需要多打些字母
这里我给出一种技巧,可以使程序看起来简洁直观明了

比如定义一个串口发送的结构,缓冲区是256字体,并环形利用
typedef    unsigned char    u8
typedef    u8        bool
===============================
typedef        struct
{
        bool        IsOpen;
        u8        CurPos;
        u8        EndPos;
        u8        Buffer[256];
} 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_COMM  Comm;

可是当你停止使用USART时,这256字节不就浪费了吗...
移去做别的用时,只能按照字节访问,想必也会很不爽吧...
但有了宏就没问题了,比如
===============================================
typedef   struct
{
    u16 Address;
    u8  Code;
    u8  Check;
} T_REMOTE;

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

#define Remote    *(T_REMOTE*)&Comm.Write.Buffer[100]

================================================
此时当USART功能停止使用后,这256字节就完全释放出来了....
当作这种技巧的作用还有很多,比如按字节接收数据,但按照结构体来读取使用,等等...
就不一一列出来了...

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2009-3-17 11:08:21 | 显示全部楼层
下面没看明白,局部变量?

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

出0入0汤圆

发表于 2009-3-17 11:10:05 | 显示全部楼层
不错,指向结构体的指针,强制类型转换。

出330入0汤圆

发表于 2009-3-17 11:15:15 | 显示全部楼层
留待观察

出0入0汤圆

 楼主| 发表于 2009-3-17 11:15:27 | 显示全部楼层
首先要知道typedef,就不多说

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

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


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

出0入0汤圆

 楼主| 发表于 2009-3-17 11:17:23 | 显示全部楼层
在c++中,这种用法的优势,被“引用”所取代...

出0入0汤圆

发表于 2009-3-17 11:58:30 | 显示全部楼层
学习了!!
MARK

出0入296汤圆

发表于 2009-3-17 12:02:22 | 显示全部楼层
地址绑定……
我一般用一个宏来处理

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

以楼主的应用为例:

TYPE_CONVERSION(Comm.Write.Buffer,T_REMOTE)

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

出0入0汤圆

发表于 2009-3-17 12:15:15 | 显示全部楼层
"union不能在struct内部使用"

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


(原文件名:Image0251.JPG)

出0入0汤圆

发表于 2009-3-17 12:24:24 | 显示全部楼层
原来是这个东东,第一次用时就碰到字节对齐问题。。。。。

出0入0汤圆

发表于 2009-3-17 14:23:55 | 显示全部楼层
MARK

出10入95汤圆

发表于 2009-3-17 22:42:44 | 显示全部楼层
留待观察

出0入0汤圆

发表于 2009-3-23 23:58:59 | 显示全部楼层
我也在用
struct DownPkt
{
        unsigned int  Addr
        unsigned char command;
        union {
                unsigned int Int;      
                unsigned char ch[2];
                } Dat;
        unsigned char ETX;
}down;
unsigned char *IBuf;

IBuf=(unsigned char *)&down;

down.Addr就可以直接用了,向IBuf[0]中写数就可以通过down.Addr直接用了

出0入0汤圆

发表于 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;
}

出0入0汤圆

发表于 2009-3-24 12:00:57 | 显示全部楼层
一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。

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

出0入0汤圆

发表于 2009-3-24 16:13:02 | 显示全部楼层
注意对齐就行了

出0入0汤圆

发表于 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

出0入0汤圆

发表于 2009-6-6 00:07:13 | 显示全部楼层
技巧 技巧!!技巧就是垃圾的代名词!!!

出0入0汤圆

发表于 2009-6-6 09:44:00 | 显示全部楼层
楼上说的有一定的道理。

出0入0汤圆

发表于 2010-8-10 23:15:22 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-10-6 09:36:26 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-10-6 15:47:10 | 显示全部楼层
不错啊,太深奥了

出0入0汤圆

发表于 2010-10-6 16:37:20 | 显示全部楼层
mark

出0入9汤圆

发表于 2010-10-6 17:18:10 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-10-6 19:17:38 | 显示全部楼层
mark

出0入0汤圆

发表于 2014-8-15 23:08:13 | 显示全部楼层
MARK ! 学习

出0入0汤圆

发表于 2014-8-26 14:52:14 | 显示全部楼层
我还以为你说的是柔性数组的知识呢,原来不是啊

出0入0汤圆

发表于 2015-7-23 09:48:42 | 显示全部楼层
学习一下
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 00:32

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表