《MIT 6.828 Lab 1 Exercise 4》实验报告
本实验链接:mit 6.828 lab1 Exercise 4。
题目
Exercise 4. Read about programming with pointers in C. The best reference for the C language is The C Programming Language by Brian Kernighan and Dennis Ritchie (known as 'K&R'). We recommend that students purchase this book (here is an Amazon Link) or find one of MIT's 7 copies.
Read 5.1 (Pointers and Addresses) through 5.5 (Character Pointers and Functions) in K&R. Then download the code for pointers.c, run it, and make sure you understand where all of the printed values come from. In particular, make sure you understand where the pointer addresses in printed lines 1 and 6 come from, how all the values in printed lines 2 through 4 get there, and why the values printed in line 5 are seemingly corrupted.
解答
题目包括两部分:一是阅读《The C Programming Language》,二是运行pointers.c文件并理解其输出。
一、阅读《The C Programming Language》
已阅读完成《The C Programming Language》第5.1~5.5节的内容,并输出学习笔记。
二、 运行pointers.c文件并理解其输出
void f(void)
{
int a[4];
int *b = malloc(16);
int *c;
int i;
printf("1: a = %p, b = %p, c = %p\n", a, b, c);
c = a;
for (i = 0; i < 4; i++)
a[i] = 100 + i;
c[0] = 200;
printf("2: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]);
c[1] = 300;
*(c + 2) = 301;
3[c] = 302;
printf("3: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]);
c = c + 1;
*c = 400;
printf("4: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]);
c = (int *) ((char *) c + 1);
*c = 500;
printf("5: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]);
b = (int *) a + 1;
c = (int *) ((char *) a + 1);
printf("6: a = %p, b = %p, c = %p\n", a, b, c);
}
运行前我先写出自己对6个输出的猜测,运行后发现第1和第5个输出猜错了,其他4个猜对了。
第1个输出是打印3个局部变量的地址,我以为a,b,c的内存地址是紧挨着的,因此猜测b的地址比a的大16,c的地址比b的大4.运行结果却是:
1: a = 0x7ffc06689160, b = 0x556fb6ccc260, c = 0xf0b2ff
。问题出在哪里?后来我才意识到指针的值实质上是它所指向的内存地址,而不是指针本身的内存地址。要想获取指针本身的内存地址,要在指针前面加上取址符号&。于是我对指针b和c加上&后再编译运行,结果为1: a = 0x7ffef6a4c1c0, &b = 0x7ffef6a4c1b0, &c = 0x7ffef6a4c1b8
。可见变量a,b,c的内存地址是在栈内紧挨着的。注意由于我用的是64位系统,指针是用8个字节存储。不过有个问题没想明白:定义局部变量的顺序是a -> b -> c,但在栈中的地址从小到大却是b -> c -> a,为什么不一致?有待研究。第2个输出是直接对数组元素赋值后再打印数组内容,很简单。此处的目的应该是展示最直接的访问数组元素的方式:数组名加下标。
第3个输出是使用各种方式对数组元素赋值后再打印数组内容,也很简单。值得注意的是
3[c]
的写法居然也是合法的,因为C编译器直接将其转换成*(3+c)
。第4个输出展示了:对指向数组的指针加上(或减去)N,相当于访问数组中当前元素的后面(或前面)第N个元素。
第5个输出有点意思,指针c原来指向a[1],接下来被修改为指向a[1]的第2个字节,然后再修改c的值,这时a[1]和a[2]的值都会受影响。修改前a[1]=0x00000190, a[2]=0x0000012b. 而500=0x000001f4,因此我猜测修改后a[1]=0x00000001,a[2]=0xf400012b.运行结果却是a[1]=0x0001f490, a[2]=0x00000100. 为什么?原来是字节序在作怪!我电脑是小端字节序,而我按照大端字节序来做了。
第6个输出表明指针加减某个整数对应的内存偏移量取决于指针的类型。
《MIT 6.828 Lab 1 Exercise 4》实验报告的更多相关文章
- [操作系统实验lab3]实验报告
[感受] 这次操作系统实验感觉还是比较难的,除了因为助教老师笔误引发的2个错误外,还有一些关键性的理解的地方感觉还没有很到位,这些天一直在不断地消化.理解Lab3里的内容,到现在感觉比Lab2里面所蕴 ...
- Ucore lab1实验报告
练习一 Makefile 1.1 OS镜像文件ucore.img 是如何一步步生成的? + cc kern/init/init.c + cc kern/libs/readline.c + cc ker ...
- ucore操作系统学习(三) ucore lab3虚拟内存管理分析
1. ucore lab3介绍 虚拟内存介绍 在目前的硬件体系结构中,程序要想在计算机中运行,必须先加载至物理主存中.在支持多道程序运行的系统上,我们想要让包括操作系统内核在内的各种程序能并发的执行, ...
- 《ucore lab3》实验报告
资源 ucore在线实验指导书 我的ucore实验代码 练习1:给未被映射的地址映射上物理页 题目 完成do_pgfault(mm/vmm.c)函数,给未被映射的地址映射上物理页.设置访问权限的时候需 ...
- 《ucore lab1 exercise5》实验报告
资源 ucore在线实验指导书 我的ucore实验代码 题目:实现函数调用堆栈跟踪函数 我们需要在lab1中完成kdebug.c中函数print_stackframe的实现,可以通过函数print_s ...
- 《ucore lab8》实验报告
资源 ucore在线实验指导书 我的ucore实验代码 练习1: 完成读文件操作的实现(需要编码) 题目 首先了解打开文件的处理流程,然后参考本实验后续的文件读写操作的过程分析,编写在sfs_inod ...
- 《ucore lab7》实验报告
资源 ucore在线实验指导书 我的ucore实验代码 练习1: 理解内核级信号量的实现和基于内核级信号量的哲学家就餐问题(不需要编码) 题目 完成练习0后,建议大家比较一下(可用meld等文件dif ...
- 《ucore lab6》实验报告
资源 ucore在线实验指导书 我的ucore实验代码 练习1: 使用 Round Robin 调度算法(不需要编码) 题目 完成练习0后,建议大家比较一下(可用kdiff3等文件比较软件) 个人完成 ...
- 《ucore lab5》实验报告
资源 ucore在线实验指导书 我的ucore实验代码 练习1: 加载应用程序并执行(需要编码) 题目 do_execv函数调用load_icode(位于kern/process/proc.c中) 来 ...
- 《ucore lab4》实验报告
资源 ucore在线实验指导书 我的ucore实验代码 练习1:分配并初始化一个进程控制块 题目 alloc_proc函数(位于kern/process/proc.c中) 负责分配并返回一个新的str ...
随机推荐
- The Preliminary Contest for ICPC Asia Xuzhou 2019 【 题目:so easy】{并查集维护一个数的下一个没有被删掉的数} 补题ING
题意:给[1,n],n个数,有两种操作: 1 x,删去x2 x,查询还未被删去的数中大于等于x的最小的数是多少. input: output: 做法:按照并查集的方法压缩路径 代码: #include ...
- mysql远程服务密码修改
GRANT ALL PRIVILEGES ON *.* TO root@"%" IDENTIFIED BY "root"; FLUSH PRIVILEGE ...
- 037_自动添加防火墙规则,开启某些服务或端口(适用于 RHEL7)
#!/bin/bash#设置变量定义需要添加到防火墙规则的服务和端口号#使用 firewall-cmd --get-services 可以查看 firewall 支持哪些服务 service=&quo ...
- 利用模板和C++11特性实现的智能指针-作用同share_ptr
根据C++11特性实现,基本上实现了同SharePtr同样的功能,有时间继续优化.之前一直以为引用计数是一个静态的int类型,实际上静态值是不可以的.之前项目中总是不太习惯使用智能指针.通过自实现的方 ...
- php foreach 中使用&时注意
结果: 没看懂的可以参考 :https://blog.csdn.net/ghostyusheng/article/details/79925351
- HDOJ->考新郎(sdut1021)
考新郎 Problem Description 在一场盛大的集体婚礼中,为了使婚礼进行的丰富一些,司仪临时想出了有一个有意思的节目,叫做"考新郎",具体的操作是这样的: 首先,给每 ...
- centos6中安装VMware Tools
使用的是centos6.8,其他6版本方法大致相同. 1 .工具/原料1)安装过虚拟机软件的计算机2)linux操作系统 3)虚拟机配置VMware tools文件, 点击工具栏上的[虚拟机],然后选 ...
- HDU 4393 Throw nails(贪心加模拟,追及问题)
题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=115361#problem/D 题意大致是:给出最多50000个人,拥有最初速度 ...
- CF1208A
CF1208A 题意: 就是把斐波那契数列的+改成异或,求第n项的值. 解法: 又是一个人类智慧题,打表找规律. 可以发现答案在 $ a,b,a⊕b $ 三个数中循环 CODE: #include&l ...
- MyBatis错误:The server time zone value '?泄???????' is unrecognized or represents more t
原文地址:http://blog.csdn.net/oppo5630/article/details/52162783 解决java.sql.SQLException: The server time ...