这个宏定义怎么做?

lijian22500 2009-09-03 04:06:09
用一个宏定义FIND求一个结构体CTYPE里某个变量CNUM相对了CTYPE的编移量。
如:stuct student
{
int a;
char b[20];
double ccc;
}
则:
FIND(student,a); //等于0
FIND(student,b);//等于4



...全文
313 31 打赏 收藏 转发到动态 举报
写回复
用AI写文章
31 条回复
切换为时间正序
请发表友善的回复…
发表回复
zbihong 2009-09-05
  • 打赏
  • 举报
回复
学习学习!
lijian22500 2009-09-05
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 yshuise 的回复:]
c++已经不这样做了。
直接:
&student::a;
&student::b;
&student::CCC;
[/Quote]

要是用C++可以这样用^_^
yshuise 2009-09-05
  • 打赏
  • 举报
回复
c++已经不这样做了。
直接:
&student::a;
&student::b;
&student::CCC;
VICTOR_CYC 2009-09-05
  • 打赏
  • 举报
回复
学习了
lijian22500 2009-09-05
  • 打赏
  • 举报
回复
谢谢提示offsetof这个系统宏,我还真不知道有这个定义
lijian22500 2009-09-05
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 supermegaboy 的回复:]
引用 12 楼 lijian22500 的回复:
引用 11 楼 supermegaboy 的回复:
引用 10 楼 lijian22500 的回复:
我们程序中的NULL为0, 就是0地址, 那么从0开始多少是系统不用的.就是不存放代码,做栈或堆使用.


虽然NULL常被定义为0,但NULL不是0!更不是0地址!NULL被定义为0只不过是NULL的一种实现方式。

听的像此零非彼零,彼零非此零一样.


NULL表示空,就是什么也没有,但在实际环境中如何表示什么也没有呢??总得有个东西表示这个什么也没有吧?0就被作为这个实现之一了。

你的问题,在标准库中是有一个不可移植的实现的,叫offsetof,这个宏不同实现不一定有,那个0并非指地址0,它表示偏移为0的地方,就是结构的起始地址。
[/Quote]

本来觉的这样也可以,但是C语言中没有地址减地址的操作
#define FIND(type,member) (&( ((type*)0x12345678)->member) - (type*)0x12345678)
只能转成unsigned int 来操作
#define FIND(type,member) ((unsigned int)&( ((type*)0x12345678)->member) - (unsigned int)0x12345678)
其中0x12345678为内存中任意一个地址. 我还是觉得这个NULL(0)就当地址0来看好.要不然真真的地址0又该怎么表示呢?
GumpMeteor 2009-09-05
  • 打赏
  • 举报
回复
受教了,
aozhi 2009-09-05
  • 打赏
  • 举报
回复
不就是offsetof的定义吗?
不同编译器有不同的定义。
/* Keil 8051 */
#define offsetof(s,m) (size_t)&(((s *)0)->m)
/* Microsoft x86 */
#define offsetof(s,m) (size_t)(unsigned long)&(((s *)0)->m)
/* Motorola coldfire */
#define offsetof(s,memb) ((size_t)((char *)&((s *)0)->memb-(char *)0))
/* GNU GCC 4.0.2 */
#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
richarddahn 2009-09-05
  • 打赏
  • 举报
回复
学习了~
asimay 2009-09-05
  • 打赏
  • 举报
回复
mark
liyudefly 2009-09-04
  • 打赏
  • 举报
回复
嗯,Linux编程中的经典做法
飞天御剑流 2009-09-04
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 lijian22500 的回复:]
引用 11 楼 supermegaboy 的回复:
引用 10 楼 lijian22500 的回复:
我们程序中的NULL为0, 就是0地址, 那么从0开始多少是系统不用的.就是不存放代码,做栈或堆使用.


虽然NULL常被定义为0,但NULL不是0!更不是0地址!NULL被定义为0只不过是NULL的一种实现方式。

听的像此零非彼零,彼零非此零一样.
[/Quote]

NULL表示空,就是什么也没有,但在实际环境中如何表示什么也没有呢??总得有个东西表示这个什么也没有吧?0就被作为这个实现之一了。

你的问题,在标准库中是有一个不可移植的实现的,叫offsetof,这个宏不同实现不一定有,那个0并非指地址0,它表示偏移为0的地方,就是结构的起始地址。
M_S_D_N 2009-09-04
  • 打赏
  • 举报
回复
在VC6中有这个宏定义。
versaariel2009 2009-09-04
  • 打赏
  • 举报
回复
学习学习
lijian22500 2009-09-04
  • 打赏
  • 举报
回复
迷糊了
lijian22500 2009-09-04
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 supermegaboy 的回复:]
引用 10 楼 lijian22500 的回复:
我们程序中的NULL为0, 就是0地址, 那么从0开始多少是系统不用的.就是不存放代码,做栈或堆使用.


虽然NULL常被定义为0,但NULL不是0!更不是0地址!NULL被定义为0只不过是NULL的一种实现方式。
[/Quote]
听的像此零非彼零,彼零非此零一样.
WizardOz 2009-09-04
  • 打赏
  • 举报
回复
很好,很强大
lbh2001 2009-09-04
  • 打赏
  • 举报
回复
#define offsetof(s, m) ((size_t)((char *)&((s *)0)->m - (char *)(s *)0))

//对类型转换后的空指针的减法是为了确保即使空指针的内部表示不是0的时候也能正确计算出偏移
//转换成(char *)指针可以确保计算出的偏移是字节偏移
wissup 2009-09-04
  • 打赏
  • 举报
回复
哥们,标准C里边好像提供了offsetof的宏的吧,定义在stddef.h中,结果为size_t的值,单位为字节!你平台不支持??

关于这样的宏的解释:#define offsetof(type,field) ((size_t) & ((type *) 0 ->field)
1、在C语言中的每个指针类型都有一个特殊值,称为null指针。它不同于该类型的每个有效指针,而是等价于null指针常量。C语言中的null指针常量是取值为0的任何整数常量表达式或可以转换成类型void*的表达式。

2、标准C语言把NULL宏定义为null指针常量

3、有些C语言实现允许在间接选择运算符左边使用null指针,然后对结果采用地址运算符&和将这个结果转换成整型,可以得到结构中成员的偏移量(字节)。标准中并没有显示允许或是禁止这种做饭,但这通常是可行的。

综上所述,其实这里并不能讨论这个0是啥意思,你要从这个0那个0讨论,估计是见招拆招,只能说C语言的实现支持这种做法,而这种做法也挺好,不会产生歧义和冲突。

而且,关于指针到底是不是只是一个地址这么简单,请从以下方向参考:一个是信息的存储表示,计算机的寻址模型,以及对存储区域的对齐限制。这样你对指针就有更好的理解。这样你对上面这种的做法的由来或是说为什么标准不禁止或是允许,也会有自己更深的理解。
我也只是有个一知半解,所以关于这个内容就不发表高论了,说了也是不详细的。只是跟大家共同探讨,呵呵呵!
whg01 2009-09-04
  • 打赏
  • 举报
回复
是对的,定义了一个truct指针,指向地址0x0000。然后计算相应成员的地址,取得的自然就是相对地址。
加载更多回复(11)

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧