免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3120 | 回复: 13
打印 上一主题 下一主题

结构体的问题,欢迎指点 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-07-08 12:32 |只看该作者 |倒序浏览
有没有人玩过这样的问题:有一个结构体,动态的取一个成员变量的值,怎么实现?
比如:
struct aaa { int a ; int b } bbb;

char name[4];
strcpy( name, "b" );

怎么获取到name这个变量指定的成员的值?

论坛徽章:
0
2 [报告]
发表于 2008-07-08 12:34 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
3 [报告]
发表于 2008-07-08 12:39 |只看该作者
你是想说associative arrays?抱歉,C做不到,你可以看看PHP和Perl。

论坛徽章:
0
4 [报告]
发表于 2008-07-08 12:41 |只看该作者
原帖由 bosi_cat 于 2008-7-8 12:32 发表
有没有人玩过这样的问题:有一个结构体,动态的取一个成员变量的值,怎么实现?
比如:
struct aaa { int a ; int b } bbb;

char name[4];
strcpy( name, "b" );

怎么获取到name这个变量指定的成员的值?


...................

[ 本帖最后由 system888net 于 2008-7-8 12:59 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2008-07-08 12:49 |只看该作者
没猜错你的意思的话,大概可以这么写,

  1. struct {
  2.     const char *fieldname;
  3.     unsigned long fieldoff;
  4. } offsets[] = {
  5. #define    OFFSETNAME(x)    { .fieldname = #x, .fieldoff = offsetof(struct aaa, x), }
  6. #define    ENDOFFSETNAME   { .fieldname = NULL, }
  7.     OFFSETNAME(a),
  8.     OFFSETNAME(b),
  9.     ENDOFFSETNAME
  10. };


复制代码

然后可以根据name找到其offset,然后通过类型强制转换来读name对应的field。

--代码随手写的,仅达意,未必能编译

论坛徽章:
8
CU大牛徽章
日期:2013-04-17 10:59:39CU大牛徽章
日期:2013-04-17 11:01:45CU大牛徽章
日期:2013-04-17 11:02:15CU大牛徽章
日期:2013-04-17 11:02:36CU大牛徽章
日期:2013-04-17 11:02:58技术图书徽章
日期:2013-12-04 10:48:50酉鸡
日期:2014-01-03 10:32:30辰龙
日期:2014-03-06 15:04:07
6 [报告]
发表于 2008-07-08 13:57 |只看该作者
我做过。

需求是:
    1、将预定义的c结构体写成固定格式的xml字符流,或从xml字符流中恢复此c结构体。
    2、此类操作逻辑相对固定,能否写成通用函数?


思路:
1、使用offsetof宏求得c结构体中每个字段相对于指向该结构体的指针的偏移。

例:
struct aa
{
  int I1; //offsetof(aa,I1) = 0
  int I2; //offsetof(aa,I2) = 4
}

若 aa * point = &x, 则 *(int *)((void *) point + offsetof(aa,I1))就相当于point->I1


2、生成一个全局对应表,记录struct名、成员变量偏移、成员变量数据类型以及它们对应的字符串名称(如"aa"、"I1"、"I2"等)
我当时定义了一组宏,很简单就可完成这个工作。

3、没啥了。查表、转换而已(如 输入“aa->I1 = 2”或"<aa><I1>2</I1></aa>",就将其转换为 aa a1; *(int *)((void*)&a1 + offsetof(aa,I1)) = 2)。
这里也可以定义成宏。



注意: 这是我当时在c中实现的方法,非常丑陋;c++中提供有更好的方法(请 google 搜索 指向成员变量的指针 的相关内容)。
由于当初实现时没有相关经验,甚至其中的offsetof宏也是我自己杜撰的;后来与c++代码混编时被编译器提示用成员变量指针代替offsetof宏,才知道自己又重新发明了轮子。

不过,用c++实现的话,最好的办法还是采用“序列化”模式(参考c++流设计思路;不过它是“流”向普通文件,我是“流”向xml格式缓冲区而已);所以也懒得重构这个东东了,干脆用类似机制重新写了个通用的“可序列化到xml”基类。

另外,微软新近推出的WPF,从它的核心技术之一“依赖属性(DependencyProperty)”的声明、使用方式看,其内部实现显然也采用了类似的思路。


PS:
指向成员变量的指针语法如下:int aa::*ptr = &aa::I1
以后,若有aa x1;则 *(x1.ptr)就相当于x1.I1
这个办法可以避免传入的结构体类型不匹配导致程序崩溃(俺当初是干脆引入模板参数推导机制,搞了个c+泛型的BT东东-_-|||;这个丑陋实现也是后来重写时改用 可序列化到xml 类机制的原因之一)。

这是offsetof宏的定义:
#define offsetof(structName,item) (size_t)&(((structName *)0)->item)

原理: 强制转换0为structName *;则 &(((structName *)0)->item)就是item相对于结构体首字节的偏移量;为避免指针相加警告,因而又将其强制转换为size_t。

论坛徽章:
0
7 [报告]
发表于 2008-07-08 14:02 |只看该作者
楼上一写就一大片呀

论坛徽章:
0
8 [报告]
发表于 2008-07-09 23:38 |只看该作者
谢谢大家,好像有点眉目了,我再琢磨琢磨

论坛徽章:
0
9 [报告]
发表于 2008-07-10 07:36 |只看该作者
我写过一个代码,根据变量类型和内存对齐原则,可以顺序访问结构体内变量的指针,不知道楼主需要这个不如果需要,我可以告诉你怎么做。限制是:必须顺序访问,必须知道结构体变量类型,或者其长度

论坛徽章:
0
10 [报告]
发表于 2008-07-10 19:37 |只看该作者
原帖由 bosi_cat 于 2008-7-8 12:32 发表
有没有人玩过这样的问题:有一个结构体,动态的取一个成员变量的值,怎么实现?
比如:
struct aaa { int a ; int b } bbb;

char name[4];
strcpy( name, "b" );

怎么获取到name这个变量指定的成员的值?



看不懂
bbb从头到尾就出现了一次
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP