Problem 1: Meet The Flintstones(斯坦福编程范例公开课作业5解答)

斯坦福编程范例的公开课作业5的Problem 1:Meet The Flintstones 题干描述:

有两个结构体的定义如下:

typedef struct rubble { // need tag name for self-reference
   int betty;
   char barney[4];
   struct rubble *bammbamm;
} rubble;
typedef struct {
   short *wilma[2];
   short fred[2];
   rubble dino;
} flintstone;
然后用图的形式准确描述在执行完以下给出的代码后,计算机内存的结构。

rubble *simpsons;
flintstone jetsons[4];
simpsons = &jetsons[0].dino;
jetsons[1].wilma[3] = (short *) &simpsons;
strcpy(simpsons[2].barney, "Bugs Bunny");
((flintstone *)(jetsons->fred))->dino.bammbamm = simpsons;
*(char **)jetson[4].fred = simpsons->barney + 4;
我们先来大体的看一下这些代码,基本都是一些赋值的操作,指针在这里面的

具体作用就是定位,指示要写入内容的位置。
下面我们给出上述两个结构体的存储结构,


因为第二个结构体flinstone包括第一个结构体rubble,所以我们将这两个结构体结合为

一个结构来画图了,编译器根据结构体成员定义的顺序来开辟内存空间。


我们来逐行分析代码:

rubble *simpsons;
这行代码的作用就是定义一个指向rubble类型的指针变量simpsons。

flintstone jetsons[4];
这行代码是定义了一个flintstone类型的结构体数组,有四个元素,数组名字叫jetsons。

此时 内存结构应该是这样的:



simpsons = &jetsons[0].dino;
这行代码将咱们的rubble *simpsons指针赋值为jetsons[0]结构体里面的dino成员的地址

内存结构变为下图:(指向了jetsons[0]所包含的rubble结构体的首地址)



jetsons[1].wilma[3] = (short *) &simpsons;
表面看这段代码出现了下表越界的情况,因为指针只是指示一个地址,我们不用管那么

多,按实际意义来走,jetsons[1]表示的是第二个flinstone结构体,wilma[3]是距离

wilma[0]三个(short *)步长的地址,jetsons[1].wilma[3]实际指向的位置是

jetsons[1].dino.betty(如下图红色方框标示的位置),然后我们将simpsons的地址强制类型

转换为(short *)类型,并将其赋给jetsons[1].dino.betty。此时jetsons[1].dino.betty这四个

字节的内容就是simsons的地址.也就是说jetsons[1].dino.betty指向simsons。



strcpy(simpsons[2].barney, "Bugs Bunny");
根据上面的处理方法,我们知道了指针的作用就是指示地址,simpsons[2]指的是距离

simpsons[0]两个sizeof(rubble类型)步长的位置,也就是距离simpsons[0]八个字节的位置,实际上就是jetsons[1].dino的位置,相应的simpsons[2].barney就是jetsons[1].dino.barney

,现在将"Bugs Bunny"赋值到barney内,又因为barney只有四个字节,"Bugs Bunny"则

需要占(4+1+5+1 = 11)个字节,所以字符串还会占用jetsons[1].dino.bammbamm和

jetsons[2].wilma[0]的空间。如下图所示:



((flintstone *)(jetsons->fred))->dino.bammbamm = simpsons;

这一行代码可能比较难理解一点,首先说明一点,flintstone结构体的dino成员的地址其实就是距离flintstone结构体首地址12个字节的位置,理,flintstone.dino.bammbamm

就是距离首地址20个字节的位置。

那么((flintstone *)(jetsons->fred))这部分代码的作用是将jetsons->fred强制类型转换

为一个(flintstone *)的指针,也就是说将jetsons->fred的位置变成了一个flintstone类型结构体的首地址。jetsons->fred实际上指的就是jetsons[0]->fred[0](如同数组a的首地址就是a[0]元素一样),那么成员dino.bammbamm就是从当前位置(jetsons[0]->fred[0])向后找

20个字节,即jetsons[1].wilma[1]的位置,将jetsons[1].wilma[1]赋值为simpsons。

结果如下图:



最后一行代码啦!!

*(char **)jetson[4].fred = simpsons->barney + 4;
虽然没有jetson[4]但是我们依然知道它在内存中是什么样子的(如下图),

simpsons->barney + 4的位置就是jetson[0].dino.barney + 4(字节)的位置,(char **)

操作将步长设置为了1字节,jetson[0].dino.barney + 4(字节)的位置就是

jetson[0].dino.bammbamm的位置,即jetson[4].fred指向jetson[0].dino.bammbamm.



到此这个内存结构图也就成型了。

我们总结一下,指针指示的是内存的地址,即内存的位置,我们只要找到初始位置,

然后确定步长(不同类型的步长不同),再按要求走相应的步数就可以到达目的地啦。

沿途的风景。。。。。。








  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值