结构体指针,地址指向哪里?

玉怀一捧雪 2014-08-30 10:44:06

unsigned char buf[4]={0,0,12,1}; //12:00 星期一

struct time
{
unsigned char sec;
unsigned char min;
unsigned char hour;
unsigned char day;
};

struct time dat;
struct time *pbuf=&dat;

void main(void)
{
unsigned char i;
unsigned char *point=(unsigned char*)pbuf;
for(i=0;i<4;i++)
{
*point++=buf[i];
}
while(1);
}

一直困惑我的是对于结构体指针,它的地址加一,*pbuf++指向的应该是下一个成员。
可是它并不像一般指针一样,可以*pbuf++=buf[0]; 使用时应该是pbuf->sec=buf[0];
上面mian里面使用了*point来指向结构体指针,这个我着实不是很明白,希望能帮忙解答疑惑
...全文
648 点赞 收藏 8
写回复
8 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
花草清香 2014-09-02
x86/debian gnu linux/gcc
vi struct_point.c

#include <stdio.h>
unsigned char buf[4]={0,0,12,1}; //12:00 星期一

struct time
{
unsigned char sec;
unsigned char min;
unsigned char hour;
unsigned char day;
};

struct time dat;
struct time *pbuf=&dat;

void main(void)
{
unsigned char i;
unsigned char *point=(unsigned char*)pbuf;
for(i=0;i<4;i++)
{
*point++=buf[i];
}
while(1);
}


gcc -g struct_point.c

1. nm a.out

see the buf's, dat's, pbuf,s address.

2. gdb a.out

To be sure point's address is the -0x8(%ebp), i's address is -0x1(%ebp)

3. objdump -dS a.out > a.txt

unsigned char *point=(unsigned char*)pbuf;
80483e2: a1 38 96 04 08 mov 0x8049638,%eax
80483e7: 89 45 f8 mov %eax,-0x8(%ebp) ;copy pbuf's value to point
for(i=0;i<4;i++)
80483ea: c6 45 ff 00 movb $0x0,-0x1(%ebp) ;i's address is -0x1(%ebp)
80483ee: eb 18 jmp 8048408 <main+0x2c>
{
*point++=buf[i];
80483f0: 0f b6 45 ff movzbl -0x1(%ebp),%eax
80483f4: 0f b6 90 34 96 04 08 movzbl 0x8049634(%eax),%edx ;%edx = &buf[i]
80483fb: 8b 45 f8 mov -0x8(%ebp),%eax
80483fe: 88 10 mov %dl,(%eax) ;*point = edx's low byte
8048400: 83 45 f8 01 addl $0x1,-0x8(%ebp) ;point = point + 1(byte, address)

The use of "*point++ = buf[i];" is: -0x08(%ebp)'s content is buf[0], -0x07(%ebp)'s content is buf[1],...., -0x05(%ebp)'s content is buf[3].

My computer can't support chinese temporary.

回复
of123 2014-09-02
楼主,你的代码中,实际上是声明了一个 unsigned char 型数组,并将其地址设置为你的结构体地址了。换句话说,他是把你的结构体“映射”到了一个 unsigned char 型数组,并通过这个数组来实现访问。 这种用法是有限制条件的。因为你的结构中全为 unsigned char 成员,它才好用。
回复
zhxianbin 2014-09-01
pbuf++相当于首地址+4 Byte,那么指向的是不是就是dat2了; ------ struct time array[2]; struct time *pbuf=array; pbuf++ 就是 array[1] 的地址了;
回复
pingheng74 2014-09-01
学习了!!!
回复
玉怀一捧雪 2014-09-01

struct time
{
    unsigned char sec;
    unsigned char min;
    unsigned char hour;
    unsigned char day;   
}dat1,dat2;

struct time *pbuf=&dat1;
pbuf++;
 
pbuf++相当于首地址+4 Byte,那么指向的是不是就是dat2了;

struct time
{
    unsigned char sec;
    unsigned char min;
    unsigned char hour;
    unsigned char day;   
}dat[2]={{0,0,0,0},{1,1,1,1}};

struct time *pbuf=&dat;
pbuf++;
 
pbuf++指向的就是dat[1]了 第一种成不成立呢?
回复
zhxianbin 2014-09-01
它的地址加一,*pbuf++指向的应该是下一个成员 ----------------------- 这句话不对,应该是 结构体的首地址 + sizeof(结构体) *pbuf++=buf[0]; 使用时应该是pbuf->sec=buf[0]; ----------------------- 如果 pbuf 是一个结构体指针,确实不能这么写,因为结构体之间不能直接赋值,main 中这么写是因为定义为 unsigned char *,本质是修改结构体各个成员的值,因为正好都是 unsigned char,就像 #2 说的,实际中不要这么写,如果有一个类型不同呢,另外还有字节对齐的问题。
回复
玉怀一捧雪 2014-09-01
很容易出错?是不是point这个指针的问题。

 for(i=0;i<4;i++)
  {
      *point++=buf[i];
  }
这条语句执行往后point应该指向第5个成员的地址,但是我结构体里面就4个成员?
回复
dceacho 2014-08-30
point的类型是unsigned char * 所以也可以这样 不过一般不建议这样初始化一个结构体,很容易出问题的
回复
相关推荐
发帖
单片机/工控
创建于2007-09-28

2.6w+

社区成员

硬件/嵌入开发 单片机/工控
申请成为版主
帖子事件
创建了帖子
2014-08-30 10:44
社区公告
暂无公告