搜索
bottom↓
回复: 31

怎样把结构体的成员变量作为参数传递?

[复制链接]

出0入0汤圆

发表于 2011-8-2 08:04:46 | 显示全部楼层 |阅读模式
假设结构体a已经定义,成员变量都是整形,那么怎样才能实现下面函数的功能呢?

对结构体的成员变量赋值

fun(类型定义  variable, int vlu)

{

   a->variable = vlu;

}

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

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入31汤圆

发表于 2011-8-2 08:18:10 | 显示全部楼层
传结构体变量指针

出0入0汤圆

发表于 2011-8-2 08:18:47 | 显示全部楼层
结构体变量可以整体赋值也可以单独对成员变量赋值,随便败毒或者狗狗下基本都出来了。

出0入0汤圆

 楼主| 发表于 2011-8-2 08:30:25 | 显示全部楼层
能否举例说明一下,试了多次都失败,网络上没有搜索到相应的例子

出0入0汤圆

发表于 2011-8-2 08:31:56 | 显示全部楼层
#define list_entry(ptr, type, member) \
        ((type *)((char *)(ptr)-(unsigned long)(&((type *)NULL)->member)))
linux的源代码。

出0入0汤圆

 楼主| 发表于 2011-8-2 08:32:40 | 显示全部楼层
struct
{
   int x1;
   int x2;
   int x3;
   int x4;
} a;

那么variable应该定义成什么类型才能实现一下函数,variable可以取值为(x1~4)
fun(类型定义  variable, int vlu)

{

   a->variable = vlu;

}

-------------
修正结构体定义错误

出0入0汤圆

发表于 2011-8-2 08:52:13 | 显示全部楼层
回复【6楼】zhaojun_xf
-----------------------------------------------------------------------


typedef struct
{
   int x1;
   int x2;
   int x3;
   int x4;
} a;

那么variable应该定义成什么类型才能实现一下函数,variable可以取值为(x1~4)

fun(a*  variable, int vlu)  
{  

   variable->x1 = vlu;  //你可以加个形参作为偏移量,这样就可以确定你到底是选X1-X4中的哪一个了。

}

出0入0汤圆

 楼主| 发表于 2011-8-2 09:02:03 | 显示全部楼层
回复【7楼】lalapunk1983
-----------------------------------------------------------------------

感谢,如是要把成员变量都写在此函数中就失去意义了,正是因为这个结构体有几十个成员变量,所以才想把它用这种方式实现。
其实目的就是想把case语句缩为一句
fun(a*  variable, int vlu, int mem)   
{   
   switch (mem)
   {
   case 1: variable->x1 = vlu;  break;
   case 2: variable->x2 = vlu;  break;
   case 3: variable->x3 = vlu;  break;
   case 4: variable->x4 = vlu;  break;
   }
}

出0入0汤圆

发表于 2011-8-2 09:07:03 | 显示全部楼层
回复【8楼】zhaojun_xf
-----------------------------------------------------------------------

这样就更好办了,直接memset((unsigned int*)&variable,vlu,sizeof(variable))

出0入54汤圆

发表于 2011-8-2 09:07:10 | 显示全部楼层
回复【楼主位】zhaojun_xf
假设结构体a已经定义,成员变量都是整形,那么怎样才能实现下面函数的功能呢?
对结构体的成员变量赋值  
fun(类型定义  variable, int vlu)
{
   a->variable = vlu;
}

-----------------------------------------------------------------------

linux有这个。。
container_of(pointer,type,field),作用就是知道一个结构体中的变量地址得出这个结构体的指针。
定义是这样的
#define container_of(ptr, type, member) ({             /
         const typeof( ((type *)0)->member ) *__mptr = (ptr);     /
         (type *)( (char *)__mptr - offsetof(type,member) );})
用法举例

struct a_struct{
  unsigned char a;
  unsigned char b;
};

fun(unsgined char *variable, int vlu)
{
   struct a_struct *aa=container_of(variable,struct a_struct,a);
   aa->a = vlu;
   aa->b = 0;  /*知道结构体指针就可以对其他成员操作了*/
}

原理就是知道成员地址,然后知道结构体首地址与成员地址的偏量,然后算出首地址再强制转换。。

----------------------------------
编辑补充

出0入0汤圆

发表于 2011-8-2 09:09:24 | 显示全部楼层
回复【8楼】zhaojun_xf  
-----------------------------------------------------------------------

typedef struct
{
   int x1;
   int x2;
   int x3;
   int x4;
} a;

fun(void * p, int vlu, int mem)

{
   *((int *)p + mem) = vlu;
}

typedef struct
{
   int x1;
   int x2;
   int x3;
   int x4;
} a;

fun(void * p, int vlu, int mem)

{
   *((int *)p + mem) = vlu;
}

void main() {

        fun (&a, 100, 0);

}

前提是结构体成员都是整型

出0入0汤圆

发表于 2011-8-2 09:26:03 | 显示全部楼层
学习 TCB ECB管理的结构 ucosii中!

出0入42汤圆

发表于 2011-8-2 09:35:52 | 显示全部楼层
5楼的看不懂,lz要的是运行时的变量名.
话说用类来做的话就是setXX

出0入0汤圆

发表于 2011-8-2 10:48:06 | 显示全部楼层
fun(a*  variable, int vlu, int mem)   
{     
*((int*)variable+(mem-1)) = vlu;
}
这样呢,岂不是更节省了

出0入0汤圆

发表于 2011-8-2 11:10:55 | 显示全部楼层
如果结构体成员多,那不如就做全局的,不要传参数了,直接用全局变量,虽然不符合C推荐做法,但对嵌入式,节省时间

出0入0汤圆

 楼主| 发表于 2011-8-2 11:15:08 | 显示全部楼层
回复【15楼】888888888888
-----------------------------------------------------------------------

结构体是IC头文件里边定义的,不能更改此文件

出0入0汤圆

发表于 2011-8-2 11:55:26 | 显示全部楼层
mark!!@^^@

出0入0汤圆

发表于 2011-8-2 12:01:14 | 显示全部楼层
回复【11楼】sun_gan
回复【8楼】zhaojun_xf   
-----------------------------------------------------------------------
typedef struct
{
   int x1;
   int x2;
   int x3;
   int x4;
} a;
fun(void * p, int vlu, int mem)  
{  
   *((int *)p + mem) = vlu;  
}
typedef struct
{
   int x1;
   int x2;
   int x3;
   int x4;
} a;
fun(void * p, int vlu, int mem)  
{  
   *((int *)p + mem) = vlu;  
}
void main() {
fun ......
-----------------------------------------------------------------------

这里好你要去掉typedef吧
#include<stdio.h>

struct
{
   int x1;
   int x2;
   int x3;
   int x4;
}a;

fun(void * p, int vlu, int mem)  

{  
   *((int *)p + mem) = vlu;  
}

void main()
{
   fun (&a, 10, 0);
  // fun (&a, 10, 1);
//   fun (&a, 70, 2);
  // fun (&a, 150, 3);
   printf("%d\n",a.x1);
}

出0入0汤圆

发表于 2011-8-2 12:19:12 | 显示全部楼层
回复【楼主位】zhaojun_xf
-----------------------------------------------------------------------

既然只是赋值,那么就没有必要定义函数,使用宏就好了  
通过结构体成员变量名使用:  
#define value_set(p,n,v)   (p)->##n=(v)  
p 为结构体变量指针  
n 为结构体中的变量的名称  
v 新值  
调用:value_set(p, x1, 0)  
通过变量索引赋值,基于楼主所示例的机构体a  
#define value_set(p,n,v)   *((int *)(p)+(n)-1)=(v)
调用: value_set(p, 1, 0)

出0入0汤圆

 楼主| 发表于 2011-8-2 13:19:30 | 显示全部楼层
以上大部分方法都是通过操作结构体的成员地址实现的,而不是真正传递成员变量实现,看样子只能通过宏来实现了,如5楼的那种,因为成员变量本身是不能通过参数传递的(验证过),

出0入0汤圆

 楼主| 发表于 2011-8-2 13:23:26 | 显示全部楼层
回复【18楼】csq463276932
-----------------------------------------------------------------------

这种方法在成员变量比较多时,需要去数成员变量的位置,不很方便,更不直观

出0入0汤圆

发表于 2011-8-2 13:28:23 | 显示全部楼层
没那么复杂吧
struct  struData
{  
   int x1;  
   int x2;  
   int x3;  
   int x4;  
};

struct struData pstruData;
void Func1(struct struData * pData)
{
    pData->x1=0x33;
    ......
}

main()
{
   Func1(&pstruData);
   pstruData.x1=....;
}

也可以用强制转换的方法:
void Func1(byte * pData)
{
    struData pData;
    pData.x1=0x33;
    ......
}

   Func1((byte *)&pstruData);
   pstruData.x1=....;

出0入0汤圆

发表于 2011-8-2 13:30:48 | 显示全部楼层
回复【22楼】zhaojun_xf  
-----------------------------------------------------------------------
如果要求传名字的话那应该也就只可能用宏了,别无他法

回复【18楼】csq463276932  
-----------------------------------------------------------------------
是的,或者去掉typedef,或者以a为类型,定义一个结构体变量

出0入0汤圆

 楼主| 发表于 2011-8-2 13:35:18 | 显示全部楼层
回复【24楼】flywater 落叶
-----------------------------------------------------------------------

如果用你说的这种方法,我就没有必要来讨论了,就是不想逐个成员判断

出0入0汤圆

发表于 2011-8-2 13:41:24 | 显示全部楼层
不太明白你的意思,是要对每一人成员符值?
还是对不确定是哪一个成员符值?

出0入0汤圆

发表于 2011-8-2 13:53:03 | 显示全部楼层
如果成员全是整形的,建议成员用数组,如果结构内成员类型不同,建议用结构数组,对不确定成员操作会方便些,

出0入0汤圆

 楼主| 发表于 2011-8-2 14:07:18 | 显示全部楼层
回复【27楼】flywater 落叶
-----------------------------------------------------------------------

没错调用函数只对成员变量中的某一个变量赋值,而不是全部赋值,需要用成员变量变来传递参数,实现对此成员变量赋值的目的

出0入0汤圆

发表于 2011-8-2 14:57:40 | 显示全部楼层
首先不太清楚LZ这样做到底是为了什么

typedef struct
{   
   int x1;   
   int x2;   
   int x3;   
   int x4;   
}struct_A;

struct_A A;

给它们幅值 直接就是 A.x1=?;A.x2=?; 就可以了





如果非要通过变量传递到函数参数里面实现 也是很直接简单的

func(u32* pX, u32 vlu)
{
    *pX = vlu;
}

使用的时候就是  func((u32*)(&A.x1), 123456);

出0入0汤圆

发表于 2011-9-1 18:43:17 | 显示全部楼层
pnumber 结构中成员的地
pSur_Struct 源结构首地址
pDest_Struct 目的结构首地址


SetValu(void * pnumber,void * pSur_Struct,void * pDest_Struct,int size)
{
memcopy( (void *)(((char*)pDest_Struct)+((char*)pnumber-(char*)pSur_Struct)),pnumber,size);
}

如:

typedef struct  
{   
   int x1;   
   int x2;   
   int x3;   
   int x4;
   char x5;
   long x6;
   double x7;   
}struct_A;  // 可以是任意复杂结构



struct_A A,B,C;

SetValu(&A.x5,&A,&B,sizeof(A.x5)); // B.x5 = A.x5;  //会计算出合适的偏移地址,赋值之
SetValu(&A.x6,&A,&B,sizeof(A.x6)); // B.x6 = A.x6;

SetValu(&C.x2,&C,&A,sizeof(C.x2)); // A.x6 = C.x2;

SetValu(&C.x7,&C,&A,sizeof(C.x7)); // A.x6 = C.x7;

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

本版积分规则

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

GMT+8, 2024-5-15 23:40

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

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