当前位置:C++技术网 > 资讯 > 循环遍历结构体的实现方法和代码实现

循环遍历结构体的实现方法和代码实现

更新时间:2016-10-18 20:22:23浏览次数:1+次

    这篇文章是一篇基础文章,但是可以加深对指针的理解。因为项目中用到了这一点,对结构体的遍历变得方便,所以在此总结下。
    说实话,这个实现要说出来,大家都知道。然而在项目开发时,往往都会忽略掉。甚至有人很惊讶,结构体还能循环遍历,当看完解释,就发现,原来不过如此。所以,这里并不是展示技术,而是说明一个思维方式。
    当我发现结构体中多个成员是一样的大小组成的时候,就和数组类似了。然而通常的做法,很少提及循环遍历数组。在结构体成员太多的时候,循环遍历确实是可以让代码更加简洁。反正我就不想写重复的代码,尽可能的让代码变得精简,这也是今天写这个文章的原因。
    我在项目中应用的原型是这样的:
typedef struct
{
    ubyte_1 start_hour;
    ubyte_1 start_min;
    ubyte_1 end_hour;
    ubyte_1 end_min;
    ubyte_4 charge_rate;
}CHARGE_RATE_ITEM;
typedef struct
{
    CHARGE_RATE_ITEM item1;
    CHARGE_RATE_ITEM item2;
    CHARGE_RATE_ITEM item3;
    CHARGE_RATE_ITEM item4;
    CHARGE_RATE_ITEM item5;
    CHARGE_RATE_ITEM item6;
}HEAD;

    从这两个结构体定义里,可能你很难将HEAD结构体联系到循环遍历。一开始我也没有想到。然而确实需要逐个的去赋值或者逐个去读取结构体成员的值。而这个HEAD结构体有6个成员,每一个又有好几个成员,如果能够用循环来处理,一下子可以让代码很简单。
    当然,实现起来也是很简单的。重点是这个思维的转变,构成循环的特点就是大量的重复,而不在于数据的形式。我们在学习的时候,条件映射的会知道数组这样的可以循环遍历,而对于结构体这样的是没有认识的。只是我们在学习循环的时候,只是限于书本中的语法介绍,在思维上没有进一步的扩展,没有挖掘到循环的本质。如果能认识到,循环的前提就是大量的重复,那么你的思维对循环就很敏感。特别是,你非常讨厌重复,就可以经常发现很多地方可以用循环解决问题,而不是复制多份差不多的代码。
    项目中用的结构体看起来搞复杂了,为了简化说明,就重新定义一个简单易看的结构体吧。定义如下:
typedef struct
{
    int value1;
    int value2;
    int value3;
    int value4;
    int value5;
}CJJJS;

    结构体的成员都是int,5个成员都是int,就构成了重复。有了重复,就好用循环来解决问题了。而实现方法就是通过指针来循环遍历。
    下面是实现循环遍历结构体的代码:
#include "stdio.h"
#include "string.h"
typedef struct
{
    int value1;
    int value2;
    int value3;
    int value4;
    int value5;
}CJJJS;
void main()
{
    CJJJS cjjjs;
    int * pInt=0;
    int arr[5]={0,12,14,42,45};
    for (int i=0;i<sizeof(CJJJS)/sizeof(int);i++)
    {
        pInt = ((int*)((char*)&cjjjs + i*sizeof(int)));
        *pInt=arr[i];
    }

    for(int i=0;i<sizeof(CJJJS)/sizeof(int);i++)
    {
        pInt = ((int*)((char*)&cjjjs + i*sizeof(int)));
        printf("%d  %d\n",i,*pInt);
    }
}

    这里涉及到好几级的指针类型转换。首先是取到结构体变量的地址,然后转成char*类型,这样就可以让地址以字节为单位进行计算,计算完之后,再转为int*,这样就可以以结构体元素的类型来访问元素。
    因为结构体的元素都是等大小的,也是连续存储的,所以可以用指针操作数组的方式来操作结构体。这样在就可以用循环批量处理赋值或者输出结构体的数据。
    这也是指针灵活的地方。我们可以在各种类型之间进行自由的转换,可以跨越数据类型的限制,可以快捷的实现我们需要的效果,精简代码。