2017-2018-1 20155332 《信息安全系统设计基础》第三周学习总结
2017-2018-1 20155332 《信息安全系统设计基础》第三周学习总结
教材学习内容总结
一. 信息的储存
- a. 大多数计算机用 8bit--一个字节(byte) 作为最小寻址单位,而不是每一个位
- b. 每台计算机有一个字长(word size)指明 整数 与 指针数据 的标称大小(nominal size). 32位机虚拟地址上线就是4GB.
- c. 多字节对象被储存为 连续的字节序列, 对象的地址为所使用字节中的最小地址. 如int x =1; &x = 0x100. 则 x的四个字节储存在 0x100 0x101 0x102 0x103中
- d. C语言利用 cast 显示位, 同时可看出 大端机 与 小端机 见P28程序(中文)
- e. 利用以上程序还可以得到 符号的ASCII码(命令 man ascii 可得到ASCII字符码表) strlen(s) 不计算字符串s的末尾的 null
- f. 二进制代码是不兼容的,由于底层指令编码不同.
- g. 布尔代数 位向量 位运算 逻辑运算 逻辑右移(补0) 算术右移(补最高有效位的值). 一般对有符号数据使用算术右移
二. 整数表示
- a. 无符号数编码(binary to unsigned)
B2U_w (x ⃗ ) = ∑24_(i=0)^(w−1)▒〖x_i 2^i 〗 (即普通的二进制数) - b. 有符号数(补码(two's-complemet)编码)(binary to two's-complemet)
B2T_w (x ⃗ ) = −x_(w−1) 2^(w−1)+ ∑24_(i=0)^(w−2)▒〖x_i 2^i 〗 (即最高位取负权重) 那么−x到x的转化为 ~x+1 - c. 有符号与无符号之间的转换
保持位不变,只是改变了解释的方式. 理解见 习题2.21
考虑比较 -1<0U 会把-1隐式转化为无符号数 - d. 位扩展:
无符号位扩展:单纯在开头添0
有符号位扩展:添加最高有效位的副本
(无符号与有符号扩展与 位 扩展的转化顺序的影响:
Short sx = -12345;
Unsigned uy = sx; //uy = 0xffffcfc7 = 4294954951
即 (unsigned) x = (unsigned)(int)sx 先进行位扩展 再转化为(理解为)无符号数
而不是 (unsigned)(unsigned short) sx
e. 截断: 丢弃高位
三. 整数的运算
- a. 正常的二进制加减乘除 然后 溢出位舍去
四. 浮点数
V= 〖(−1)〗s×M×2E
符号(sign) s
尾数(significand) M为二进制小数
阶码(exponent) E 为对浮点数加权
- a.四种类型:(以s一位,E两位,M两位为例)
- b. 尾码字段:中二进制值理解为 0.11 = 0.75(十进制)设其值为f
- c.阶码字段:中二进制值理解为正常的11 = 3(十进制) 设其值为e
- 浮点数加法 没有结合性 即:(3.14 + 1e10) - 1e10 = 0 而 3.14 +(1e10 - 1e10) = 3.14
教材学习中的问题和解决过程
(一个模板:我看了这一段文字 (引用文字),有这个问题 (提出问题)。 我查了资料,有这些说法(引用说法),根据我的实践,我得到这些经验(描述自己的经验)。 但是我还是不太懂,我的困惑是(说明困惑)。【或者】我反对作者的观点(提出作者的观点,自己的观点,以及理由)。 )
- 问题1:使用32位表示数据类型int,计算表达式200300400*500会得出结果-884901888
问题1解决方案:程序验证
#include<stdio.h>
#include<stdlib.h>
int main()
{
long long a=200*300*400*500;//60000*200000=12000000000
printf("200*300*400*500=%d\n",200*300*400*500);
printf("200*300*400*500=%I64d\n",200*300*400*500);
printf("12000000000=%d\n",12000000000);
printf("12000000000=%I64d\n",12000000000);
getchar();
}
可以发现发生,int型整数
发生了溢出,只保留末32位,所以得到了-884901888这个值。
但是用长整数输出结果,则会得到
运行结果3410065408,这是无符号整数.
200*300*400*500=-884901888
200*300*400*500=3410065408
12000000000=-884901888
12000000000=12000000000
- 问题2:课后作业2.58
问题2解决方案:
int is_little_endian(){
int a = 1;
return ((char) & a);
}
- 问题3:课后作业2.59
解决方案:(x&0xFF) | (y&~0xFF)
- 问题4: 课后作业2.60
解决方案
unsigned replace_byte(unsigned x, unsigned char b, int i)
{
return (x & ~(0xFF<<(i<<3))) | (b << (i<<3));
}
- 问题5:课后作业2.61
解决方案:
- A. !~x
- B. !x
- C. !~(x>>((sizeof(int)-1)<<3))
- D. !(x&0xFF)
- 问题6:课后作业2.62
解决方案:
int_shifts_are_arithmetic()
int int_shifts_are_arithmetic(){
int x = -1;
return (x>>1) == -1;
}
代码调试中的问题和解决过程
- 问题1:.有符号数和无符号数之间的转换,所谓转换,只是针对某个n位的数,换一种解释的方式,并不改变位值。
C语言在对同时包含有符号数和无符号数的表达式时,隐性把有符号数转成无符号数,再进行计算。
书中说:这个对标准的算术运算,结果和直观无多大差异,只对<和>有差异,但我的测试结果明显不对:
if (-1 < 0u)
{
int i = 0;
}
else
{
unsigned int a = 2147483648;// 0x80000000;
int c = -2147483647;//0x80000001
int j = c - a;//j结果是1
int k = 0;
}
- 问题1解决方案第1行:-1转成无符号后变得很大,所以执行else,和直观不同
第7-9行:直观上j应该是一个很小的负数,担结果却是1
总结:尽量不要互转,除非你确定任何数值都没有问题。具体分析就是一步一步来,反正规则就是转换只改变解释方式,不改变位值,并且默认有符号转无符号。
代码托管
上周考试错题总结
- 第七章18题,错误3道,答案尚未公布,不知道哪道题目错了。以后补上。
- 第二章37题,错误15题,答案尚未公布,以后补上。
本周结对学习情况
- [20155324](http://www.cnblogs.com/wang5324/p/7616183.html)
- 结对照片 无
- 结对学习内容
- 第七章
- 第二章
- myod 的系统调用
其他(感悟、思考等,可选)
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 200/200 | 2/2 | 20/20 | |
第二周 | 300/500 | 2/4 | 18/38 | |
第三周 | 500/1000 | 3/7 | 22/60 | |
第四周 | 300/1300 | 2/9 | 30/90 |
尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进自己的计划能力。这个工作学习中很重要,也很有用。
耗时估计的公式
:Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。
-
计划学习时间:XX小时
-
实际学习时间:XX小时
-
改进情况:
(有空多看看现代软件工程 课件
软件工程师能力自我评价表)