#include <stdio.h>
#define OFFSET(Type,member) (size_t)&(((Type*)0)->member)
typedef struct goods{
int num;
int stock;
int price;
int vol;
}goods;
int FindnOutput(size_t offset, goods *h, int n,int S){
int f = 0;
for (int i = 0;i < n; i++)
{
int temp = *(int*)((size_t)(h+i) + offset);
if (temp >= S)
{
printf("%d %d %d %d",(h+i)->num,(h+i)->stock, (h+i)->price,(h+i)->vol);
f = 1;
}
}
if (!f)
{
printf("nothing");
}
return 0;
}
int main()
{
int n;
int K,S;
size_t offset;
goods G[1001];
scanf("%d",&n);
for (int i = 0; i < n; i++)
{
scanf("%d%d%d%d",&G[i].num,&G[i].stock,&G[i].price,&G[i].vol);
}
scanf("%d%d",&K,&S);
switch (K)
{
case 1:
offset = OFFSET(goods,stock);
FindnOutput(offset,G,n,S);
break;
case 2:
offset = OFFSET(goods,price);
FindnOutput(offset,G,n,S);
break;
case 3:
offset = OFFSET(goods,vol);
FindnOutput(offset,G,n,S);
break;
}
return 0;
}
以前随手写的,这是一个大一经常碰到的结构体学习的基础问题:有一种货物,用结构体来描述它,goods为货物结构,它有成员
int num;
int stock;
int price;
int vol;
进货量,库存,价格,体积
现在有一个需求,给定一个数S,我需要根据上面4个成员的情况,输出货物某个成员大于S的所有货物信息。比如我这次要输出所有价格大于10的货物,下次可能变成我要输出所有体积大于10的货物。
现在的问题是我想就设置一个函数,可以根据输入比较多种成员,减少代码量。这次比较num下次比较stock,仅仅需要调用一个函数,那这要怎么实现?
我上面的办法是用偏移量,(内核之类的经常这样使用,不过晦涩难懂)。
#define OFFSET(Type,member) (size_t)&(((Type*)0)->member)
这个宏,是:
复制点东西过来给lz参考,
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
先分析一下这个 宏的运行机理:
一共4步
1. ( (TYPE *)0 ) 将零转型为TYPE类型指针;
2. ((TYPE *)0)->MEMBER 访问结构中的数据成员;
3. &( ( (TYPE *)0 )->MEMBER )取出数据成员的地址;
4.(size_t)(&(((TYPE*)0)->MEMBER))结果转换类型。巧妙之处在于将0转 换成(TYPE*),结构以内存空间首地址0作为起始地址,则成员地址自然为偏移地址;
“3. &( ( (TYPE *)0 )->MEMBER )取出数据成员的地址;”
补充一下:
这个实现相当于获取到了 MEMBER 成员相对于其所在结构体的偏移,也就是其在对应结构体中的什么位置。
上面这两段话引用自http://bbs.chinaunix.net/thread-1917123-1-1.html
int temp = *(int*)((size_t)(h+i) + offset);
h为goods*类型,指针类型本质上是地址 也就是一个32位/64位数字,unsigned int or size_t【这种理解有失偏颇,请参考下面的链接】
http://book.2cto.com/201402/40243.html
加上offset之后就是此成员的地址了,接着*(int *)取出该成员的值。假如此成员类型为char 那就是*(char*).
不知道还有没有其他较简单的方法。
重载?==>之后再研究一下
如果可以再更新此文。
我也不知道我上面这种方法是否是最简易的,请各位提出见解。