鱼C论坛

 找回密码
 立即注册
查看: 6403|回复: 14

如何遍历结构体成员,前提不使用指针运算,例如p++

[复制链接]
发表于 2019-1-15 15:29:33 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
目前需要实时去遍历一个比较大的结构体,单个赋值太麻烦肯定有简便的方法,目的是结构体任何一个成员改变时需要做其他的处理,typedef        unsigned  int        uint16;typedef        unsigned  int        Uint16;:
struct ERROR_REG {                   /* bits   description   */            
    uint16 RsvNone:1;                /*0                     */
    uint16 DRV:1;                         /*  1                   */
    uint16 Soft_OC:1;                 /*  2                   */
    uint16 Hard_OC:1;                /*  3                   */
    uint16 rsv:1;                        /*  4                   */
    uint16 Over12V:1;                 /*  5                        */
    uint16 Low12V:1;                /*  6                            */
    uint16 CurU:1;                /*  7               */
    uint16 CurW:1;                /*  8                   */
    uint16 EEP:1;                /*  9                 */
    uint16 OU:1;                       /* 10                */
    uint16 LU:1;                       /* 11               */
    uint16 IGBT_OH:1;       /* 12            */     
    uint16 PGSignal:1;      /* 13             */
    uint16 CurCheck:1;         /* 14       */
    uint16 EFT:1;              /* 15           */
    uint16 Tune:1;               /* 16          */
    uint16 ParaSet:1;                /* 17         */
    Uint16 VdcCheck:1;        /* 18        */
    Uint16 Mul_Soft_OC:1;        /* 19        */
    Uint16 CurSensorU:1;        /* 20        */
    Uint16 CurSensorV:1;        /* 21        */
    Uint16 CurSensorW:1;        /* 22        */
    Uint16 Rsv18:9;                /* 23 - 31        */
};
  目前在尝试定义两个数组结构体然后整体进行比较,不清楚行不行?希望有知道的鱼油指点一二!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2019-1-15 15:39:05 | 显示全部楼层
目前是定义typedef struct ERROR_REG ERROR_REG_List;
ERROR_REG_List ERRORdata[2];
memcmp(&ERRORdata[0],&ERRORdata[1],sizeof(ERROR_REG_List));
不清楚这样行不行?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-1-15 15:59:12 | 显示全部楼层
本帖最后由 Croper 于 2019-1-15 16:02 编辑

如果没猜错的话你这个结构体应该长度就4个字节,刚好是整形的长度。
unsigned int i = *(int*)®
这样i里存储的就是reg里所有的数据了,然后要判断是否相同只需要比较两个整形就够?
或者直接定义成
        operator int() {return *(int*)this;}
不知道行不行
。。。
嗯好像跟你的是一样的,你的还直接一些。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-1-15 16:31:48 | 显示全部楼层
Croper 发表于 2019-1-15 15:59
如果没猜错的话你这个结构体应该长度就4个字节,刚好是整形的长度。

这样i里存储的就是reg里所有的数据 ...

你用的是C++吧,不错的方法,但是在C中不能进行结构体的整体比较,我只能是先保存在RAM中再用库函数进行比较一下,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-1-15 17:14:54 | 显示全部楼层
PythonMegmeet 发表于 2019-1-15 16:31
你用的是C++吧,不错的方法,但是在C中不能进行结构体的整体比较,我只能是先保存在RAM中再用库函数进行 ...

好像不行,我想比较的是每个元素的内容是否相同,库函数不能实现,头疼!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-1-15 17:35:23 | 显示全部楼层
本帖最后由 行客 于 2019-1-15 17:51 编辑
PythonMegmeet 发表于 2019-1-15 17:14
好像不行,我想比较的是每个元素的内容是否相同,库函数不能实现,头疼!!


你本来就是通过位域来处理的,Croper这样处理应该没问题啊,有什么问题?当然你别用operator

你是想具体到判断某几个bit位是否相同?如果那样,你直接通过两个数组元素的位运算来判断应该就可以啊。

首先这是4个字节。如果你想比较最后的9个bit位(Uint16 Rsv18:9;)是否相同,你先分别对两个数组元素和0000 0000 0000 0000 0000 0001 1111 1111做与(&)运算,前面的都置零了,最后9位不变,再比较两个数组元素与后的结果不就可以了。其他位的比较也一样。比较整体就更简单了。当然你也可以用word或byte处理处理原数组元素再做比较,不过必要性不大。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-1-15 17:51:08 | 显示全部楼层
PythonMegmeet 发表于 2019-1-15 15:39
目前是定义typedef struct ERROR_REG ERROR_REG_List;
ERROR_REG_List ERRORdata[2];
memcmp(&ERRORda ...


你的这个办法和Croper的思路差不多。不过只比较两个数组元素没有Croper的好,当然在C下就别用operator了。提醒下好好看看我上面的回复啊。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-1-16 08:44:22 | 显示全部楼层
行客 发表于 2019-1-15 17:51
你的这个办法和Croper的思路差不多。不过只比较两个数组元素没有Croper的好,当然在C下就别用operator ...

原理是这样的,但是如何去实现呢,在C中不能进行直接比较的,结构体每1ms更新一次,我想要的是比较当前结构体与上1ms的结果然后再做处理
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-1-16 09:01:41 | 显示全部楼层
PythonMegmeet 发表于 2019-1-16 08:44
原理是这样的,但是如何去实现呢,在C中不能进行直接比较的,结构体每1ms更新一次,我想要的是比较当前结 ...

你这是自己的源代码来做处理,还是截获数据做处理?如果是自己的源代码,干脆用“结构体对象.成员”来比较不就行了?如果是截获数据,再采用我那个办法。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-1-17 08:50:52 | 显示全部楼层
行客 发表于 2019-1-16 09:01
你这是自己的源代码来做处理,还是截获数据做处理?如果是自己的源代码,干脆用“结构体对象.成员”来比 ...

是自己处理,主要公司规定不允许使用指针运算,单个处理太麻烦了,还有一些更大的结构体,可能还是用链表,我再想想!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-1-17 09:32:35 | 显示全部楼层
本帖最后由 行客 于 2019-1-17 10:06 编辑
PythonMegmeet 发表于 2019-1-17 08:50
是自己处理,主要公司规定不允许使用指针运算,单个处理太麻烦了,还有一些更大的结构体,可能还是用链表 ...


如果只是处理这个结构,建议不要采用链表,这个方案应该是比较经济的办法了。
我举一个简单例子,你或许就明白了。因为一个一个的给struct ERROR_REG;赋值太麻烦,我直接用int举一个例子。
(说明:你的这个结构体正好长度4个字节,刚好就是整形int的长度。可以采用unsigned int i = *(int*)®转换到整形int。)
#include "stdio.h"

int main(int argc,const char* argv[])
{
        //int m=0xFFBF;        //二进制:1111 1111 1011 1111
        int m=0xFFFF;        //二进制:1111 1111 1111 1111
        int n=0x2EEC;        //二进制:0010 1110 1110 1100

        //假设我们想比较从右起第6下标位、第7下标位、第8下标位是否相同(以从右起第1位作为下标0),
        //那么,我们只要将两个m、n的二进制除了这3位外,其余各位转换为0既可以实现比较。即转换为:
        //m: 0000 0000 1110 0000
        //n: 0000 0000 1110 0000
        //,然后再进行比较。具体我们采用下面的方式来进行转换:
        int m1=m & 0x00E0;
        int n1=n & 0x00E0;
        if (m1==n1)
        {
                printf("相同:第6、7、8下标位\n");
        } 
        else
        {
                printf("不同:第6、7、8下标位\n");
        }
}

如果还没搞明白,你可以将m的值改成int m=0xFFBF;即二进制1111 1111 1011 1111,之后再测试一下结果,应该就明白了。

如果有疑问请继续跟帖
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-1-17 10:06:19 | 显示全部楼层
本帖最后由 人造人 于 2019-1-17 10:08 编辑
PythonMegmeet 发表于 2019-1-15 15:39
目前是定义typedef struct ERROR_REG ERROR_REG_List;
ERROR_REG_List ERRORdata[2];
memcmp(&ERRORda ...


可以使用memcmp
#include <stdio.h>
#include <stdbool.h>
#include <string.h>

typedef unsigned  int uint16;
typedef struct                                /* bits   description   */
{
        uint16 RsvNone : 1;                /*0                     */
        uint16 DRV : 1;                        /*  1                   */
        uint16 Soft_OC : 1;                /*  2                   */
        uint16 Hard_OC : 1;                /*  3                   */
        uint16 rsv : 1;                        /*  4                   */
        uint16 Over12V : 1;                /*  5                   */
        uint16 Low12V : 1;                /*  6                   */
        uint16 CurU : 1;                /*  7                   */
        uint16 CurW : 1;                /*  8                  */
        uint16 EEP : 1;                        /*  9                 */
        uint16 OU : 1;                        /* 10                */
        uint16 LU : 1;                        /* 11               */
        uint16 IGBT_OH : 1;                /* 12              */
        uint16 PGSignal : 1;                /* 13             */
        uint16 CurCheck : 1;                /* 14            */
        uint16 EFT : 1;                        /* 15           */
        uint16 Tune : 1;                /* 16          */
        uint16 ParaSet : 1;                /* 17         */
        uint16 VdcCheck : 1;                /* 18        */
        uint16 Mul_Soft_OC : 1;                /* 19        */
        uint16 CurSensorU : 1;                /* 20        */
        uint16 CurSensorV : 1;                /* 21        */
        uint16 CurSensorW : 1;                /* 22        */
        uint16 Rsv18 : 9;                /* 23 - 31   */
} ERROR_REG;

bool ErrorRegCompare(ERROR_REG *a, ERROR_REG *b)
{
        return !memcmp(a, b, sizeof(ERROR_REG));
}

int main(void)
{
        ERROR_REG a = {0xAA55};
        ERROR_REG b = a;

        if(ErrorRegCompare(&a, &b))
                printf("a == b\n");
        else
                printf("a != b\n");

        b.RsvNone = 0;
        if(ErrorRegCompare(&a, &b))
                printf("a == b\n");
        else
                printf("a != b\n");

        return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-1-21 15:25:39 | 显示全部楼层
行客 发表于 2019-1-17 09:32
如果只是处理这个结构,建议不要采用链表,这个方案应该是比较经济的办法了。
我举一个简单例子,你或 ...

现在可以了,我是这样处理的: uint32_t result_1;
    static uint32_t result_2;
    uint32_t *Errordata_LOG = NULL ;
    ERROR_REG_List Error_list;

    Errordata_LOG = (uint32_t*)(&Error_list);
    result_1 = *Errordata_LOG;
    if ((result_1 & 0xFFFFFFFF) != result_1 )
    {
        StartSaveflag = 1u;
    }
    else if((result_1 & result_2) != result_1 )
    {
        StartSaveflag = 1u;
    }
    result_2 = result_1;
    return  StartSaveflag;
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-1-21 15:26:19 | 显示全部楼层

前几天电脑坏了,我不太理解你这句是什么意思ERROR_REG a = {0xAA55};
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-1-21 15:41:06 | 显示全部楼层
PythonMegmeet 发表于 2019-1-21 15:26
前几天电脑坏了,我不太理解你这句是什么意思ERROR_REG a = {0xAA55};

变量a,4个字节,32位
ERROR_REG a = {0xAA55};

0000 0000 0000 0000 1010 1010 0101 0101

就是把变量a的内容赋值为0xAA55

uint32_t a = 0xAA55;   一个效果
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-3 06:35

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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