您的位置:首页 > 编程语言

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

2014-12-18 15:14 393 查看
斯坦福编程范例的公开课作业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.



到此这个内存结构图也就成型了。
我们总结一下,指针指示的是内存的地址,即内存的位置,我们只要找到初始位置,
然后确定步长(不同类型的步长不同),再按要求走相应的步数就可以到达目的地啦。
沿途的风景。。。。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c 指针 内存