各位牛人:小弟请教个结构体的问题,有点意思的

remmeber 2008-10-13 05:07:06
定义两个结构体如下:
typedef struct
{
short b1;
int a1;
}ST1;

typedef struct
{
short b2;
int a2;
ST1 P1;
ST1 P2;
}ST2;

。。。。
unsigned int offset;
offset = (unsigned int) &( ( (ST2*)0)->P1 );//offset = 8
offset = (unsigned int) &( ( (ST2*)1)->P1 ) ;////offset = 9
...
为什么会出现这种情况呢?小弟不百思不得其解!!

((ST2*)0)这样写法的内存又是如何处理的呢??
请教了!!!!
...全文
307 31 打赏 收藏 转发到动态 举报
写回复
用AI写文章
31 条回复
切换为时间正序
请发表友善的回复…
发表回复
xtdumpling 2008-10-17
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 kiffa 的回复:]
这是很常见的用法啊,求结构体内成员的偏移量。
[/Quote].
蘑菇摸骨 2008-10-17
  • 打赏
  • 举报
回复
MARK
malu_1982 2008-10-17
  • 打赏
  • 举报
回复
这个 貌似和 a[0] == 0[a]一个模式吧
yellowhwb 2008-10-17
  • 打赏
  • 举报
回复
一个是从0地址开始取内存,一个是从1地址开始取内存,两个结构体都一样,自然里面的每个字段的地址都相差1个字节啦!
JimmyFan2006 2008-10-17
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 JimmyFan2006 的回复:]
char* p ;
p = 0;//p指向0地址
ST2* pST2 = (ST2*)p;
[/Quote]

换成void*指针更容易理解点
void* p ;
p = 0;//p指向0地址
ST2* pST2 = (ST2*)p;
JimmyFan2006 2008-10-17
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 ztz0223 的回复:]
C/C++ code unsigned int offset;
offset = (unsigned int) &( ( (ST2*)0)->P1 );//offset = 8
offset = (unsigned int) &( ( (ST2*)1)->P1 ) ;////offset = 9
/*
这个不是瞎搞,我的解释:
1、这里都是编译时候确定的,因为定义给出来了,那么变量的地址偏移的也是确定的
2、(ST2*)0和(ST2*)1是强制地址转换,如果熟悉c++的话,就知道以前c++中的class里面的static变量是不能用
ST2::P1,不能这样用的,…
[/Quote]


offset = (unsigned int) &( ( (ST2*)0)->P1 );//offset = 8

(ST2*)0可以这样理解.
char* p ;
p = 0;//p指向0地址
ST2* pST2 = (ST2*)p;

ST2*)1可以这样理解.
	char* p ;
p = 0;
p += 1; //p指向地址为1的地方,即地址0+1的地方
ST2* pST2 = (ST2*)p;
r_swordsman 2008-10-17
  • 打赏
  • 举报
回复
lz是想定义2个结构指针吧,改成这样
typedef struct
{
short b2;
int a2;
ST1 *P1;
ST1 *P2;
}ST2;
r_swordsman 2008-10-17
  • 打赏
  • 举报
回复
肯定是瞎用
[Quote=引用 9 楼 ysuliu 的回复:]
就是瞎用~

引用 1 楼 fox000002 的回复:
这完全是在瞎用
[/Quote]
corro 2008-10-17
  • 打赏
  • 举报
回复
具体解释一下实现过程
ivan8222 2008-10-14
  • 打赏
  • 举报
回复
我觉得三楼的是对的,应该是这个结构的一个变量,相对于它起始地址的偏移量
就呆在云上 2008-10-14
  • 打赏
  • 举报
回复
	unsigned int offset;	
offset = (unsigned int) &( ( (ST2*)0)->P1 );//offset = 8
offset = (unsigned int) &( ( (ST2*)1)->P1 ) ;////offset = 9
/*
这个不是瞎搞,我的解释:
1、这里都是编译时候确定的,因为定义给出来了,那么变量的地址偏移的也是确定的
2、(ST2*)0和(ST2*)1是强制地址转换,如果熟悉c++的话,就知道以前c++中的class里面的static变量是不能用
ST2::P1,不能这样用的,就是要用0好地址的偏移,(ST2*)0)->P1
3、对数字可以强制转换来实现需要的类型比如
(int *)0,转换成int型的指针
4、之所以得到的是8和9,是因为(ST2*)0转化得到的是一个临时变量,而这样得到的是绝对地址,从0开始偏移就是8,而从1开始
当然就是9了
5、st2结构体:typedef struct
{
short b2;
int a2;
ST1 P1;
ST1 P2;
}ST2;
里面有int、short、st1、但是st1是结构体,字节对齐的时候以他内部的变量类型对齐,他里面最大的是int就是4个zijie
而st2里面最大也是int那么st2整个都是以int对齐的,到p1的时候当然偏移是8个字节
devil_zuiai 2008-10-14
  • 打赏
  • 举报
回复
由于字节对齐的缘故,所以
#pragma pack(4)

#pragma pack(2)
的结果就不一样了。
halve 2008-10-14
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 fox000002 的回复:]
这完全是在瞎用


[/Quote]
一种计算结构体内成员偏移的方法...
xadream 2008-10-13
  • 打赏
  • 举报
回复
结构体对齐问题
maybe8字节对齐
kiffa 2008-10-13
  • 打赏
  • 举报
回复
这是很常见的用法啊,求结构体内成员的偏移量。
frank_ll 2008-10-13
  • 打赏
  • 举报
回复
顶13楼
wcx1982 2008-10-13
  • 打赏
  • 举报
回复
13楼说的没错~
wcx1982 2008-10-13
  • 打赏
  • 举报
回复
可以使用这种方法通过结构成员的地址获取到结构的地址
帅得不敢出门 2008-10-13
  • 打赏
  • 举报
回复
貌似编译期就确定了

24: offset = (unsigned int) &( ( (ST2*)0)->P1 );//offset = 8
00401558 mov dword ptr [ebp-4],8
25: cout << offset << "\n";
0040155F push offset string "\n" (0047201c)
00401564 mov eax,dword ptr [ebp-4]
00401567 push eax
00401568 mov ecx,offset std::cout (0047ff88)
0040156D call @ILT+240(std::basic_ostream<char,std::char_traits<char> >::operator<<) (004010f5)
00401572 push eax
00401573 call @ILT+615(std::operator<<) (0040126c)
00401578 add esp,8
26: offset = (unsigned int) &( ( (ST2*)1)->P1 ) ;////offset = 9
0040157B mov dword ptr [ebp-4],9
  • 打赏
  • 举报
回复
学习了
加载更多回复(11)

69,371

社区成员

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

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