主要完成mod 4==0的题目,有错误望指正, 这是学校课程的作业,但是由于能力有限,题目有时也会参考其他的答案,
我觉得很好的一份答案:https://dreamanddead.gitbooks.io/csapp-3e-solutions/chapter2/2.68.html
写博客的目的是为了加深我自己的理解而已,而不是表明这些都是完完全全的我自己的开创性解答。
全篇可能使用到的函数(来自书中给出的)
typedef unsigned char *byte_pointer; void show_bytes(byte_pointer start, size_t len) { size_t i ; for(i=0;i<len;i++) { printf(" %.2x",start[i]); } printf(" "); } void show_int(int x) { show_bytes((byte_pointer)&x,sizeof(int)); }
2.55
这里show_bytes.c文件可以在官网csapp.cs.cmu.edu/3e/code.html下载。
这里需要学习的是Linux环境下c程序的编写:写好xxx.c文件,然后运行gcc xxx.c,最后会发现多出一个a.out文件,然后在命令行输入./a.out即可看到编译运行的结果了。
2.58
int is_little_endian(byte_pointer start) { if(start[0]==0xff) return 1; else return 0; } int main() { size_t m =0xff; //byte_pointer start = (byte_pointer &m); if(is_little_endian((byte_pointer)&m)==1) printf("应是小端机"); else printf("我猜是大端机"); return 0; }
为什么我觉得小端机这么好听呢?
不觉让人想到宋词《九张机》:
一张机,采桑陌上试春衣。风晴日暖慵无力, 桃花枝上,啼莺言语,不肯放人归。
两张机,行人立马意迟迟。深心未忍轻分付, 回头一笑,花间归去,只恐被花知。
三张机,吴蚕已老燕雏飞。东风宴罢长洲苑, 轻绡催趁,馆娃宫女,要换舞时衣。
四张机,咿哑声里暗颦眉。回梭织朵垂莲子,盘花易绾,愁心难整,脉脉乱如丝。
五张机,横纹织就沈郎诗。中心一句无人会, 不言愁恨,不言憔悴,只恁寄相思。
六张机,行行都是耍花儿。花间更有双蝴蝶,停梭一晌,闲窗影里,独自看多时。
七张机,鸳鸯织就又迟疑。只恐被人轻裁剪,分飞两处,一场离恨,何计再相随?
八张机,回纹知是阿谁诗?织成一片凄凉意,行行读遍,恹恹无语,不忍更寻思。
九张机,双花双叶又双枝。薄情自古多离别,从头到尾,将心萦系,穿过一条丝。
2.59
这里主要用到的是 一个并和或的运用 m = ((x&sign)|(y&~sign))
int main() { size_t sign = 0xff; //size_t == unsigned int size_t x = 0x89ABCDEF; size_t y = 0x76543210; size_t m = ((x&sign)|(y&~sign)); show_int(m); return 0; }
2.60
unsigned replace_byte (size_t x ,int i,unsigned char b) { size_t k =x; size_t n =(unsigned)i<<3; size_t sign = 0xff<<n; size_t sb = (unsigned)b<<n; return (k & ~sign) | sb; } int main() { size_t x; size_t y; x = replace_byte(0x12345678,2,0xAB); y = replace_byte(0x12345678,0,0xAB); show_int(x); show_int(y); }
2.64
C语言中!!操作表示:把这个数非零转化为1,0还是零。因为这里是逻辑判断功能,非零即为真,只有零才是假。
题目是return 1 when any odd bit of x equals 1;0 otherwise只有我一个人疑惑奇数bit是那些偶数bit是那些吗?
百度之后 : 0101110 那么奇数位就是 0 0 1 0 果然我想太多
int any_odd_one(unsigned x) { return !!(x & 0xAAAAAAAA); } int main() { printf("%d",any_odd_one(0x5)); return 0; }
(any 是任何一个就行,不是every。。。。。我的英文。。。要哭了。。。。)
2.68
参考思路为:https://dreamanddead.gitbooks.io/csapp-3e-solutions/chapter2/2.68.html
我开始没有理解题目的意思:
mask with least signficant n bits set to 1,现在理解,可能是把除最高位以外的其他位的权值都设为1吧,(或者 是理解为让n这个数的最低n位都变为1,就是有n个1的数那么我看到别人的思路blog.csdn.net/zhanyu1990/article/details/24936663用2<<(n-1)) - 1也很巧妙)
int lower_one_mask(int n) { int w = sizeof(int)<<8; return (unsigned)-1>>(w-n); //注意这里的-1一定要是强制转为无符号 } int main() { show_int(lower_one_mask(6));
show_int(lower_one_mask(17)); }
2.72
其实我不是很懂怎么通过main 函数使用这个函数,所以参考了:https://dreamanddead.gitbooks.io/csapp-3e-solutions/chapter2/2.72.html
void copy(int val,void *buf,int maxbytes) { if(maxbytes-(int)sizeof(val)>=0) { memcpy(buf,(void *)&val,sizeof(val)); printf("right "); } else printf("Errrrrr "); } int main() { int maxbytes = sizeof(int) * 10; void* buf = malloc(maxbytes); int val; val = 0x12345678; copy(val, buf, maxbytes); val = 0xAABBCCDD; copy(val, buf, 0); free(buf); return 0; }
这道题目题目中有提示:sizeof 运算返回的是无符号,所以判断大小的那一句由于是无符号的数,自然是全部>=0,改进的方法也很简单,强制类型转化,变为有符号数的操作即可。
2.76
1.void
*
malloc
(
size_t
size);
作用:可以向系统申请分配指定size个字节的内存空间
2.void *memset(void *s,int c,size_t n)
作用:将已开辟内存空间 s 的首 n 个字节的值设为值 c
void *cccalloc(size_t nmemb,size_t size)
{
if(nmemb==0||size==0) return NULL;
size_t buf_size = nmemb * size;
if (nmemb == buf_size / size) //判断是否溢出
{
void* ptr = malloc(buf_size);
memset(ptr, 0, buf_size);
return ptr;
}
return NULL;
}
int main()
{
void* p;
p = cccalloc(0x1234, 1);
if(p!=NULL)
printf("rigjt!
");
free(p);
p = cccalloc(SIZE_MAX, 2);//SIZE_MAX定义在头文件stdint.h
中
if(p == NULL)
printf("ERRRR
");
free(p);
return 0;
}
2.84
unsigned f2u(float x) { return *(unsigned*)&x;//&x取x的地址,(unsigned*)&x是把x的地址强制类型转换为unsigned,*(unsigned*)&x取转换后的值 } int float_le(float x,float y) { unsigned ux = f2u(x); unsigned uy = f2u(y); unsigned sx = ux >> 31; unsigned sy = uy >> 31; //浮点数的一个特点就是,如果大于0,则可以按unsigned位表示的大小排序。 //如果小于0则相反。注意都为0的情况即可。 //所以条件是: return ((ux<<1)==0 && (uy<<1)==0) || (!sx && sy) || (!sx && !sy && ux <= uy) || (sx && sy && ux >= uy); } int main() { printf("%d",(float_le(+0, -0))); printf("%d",(float_le(2, 3))); }
2.88
格式A | 格式B | ||
位 | 值 | 位 | 值 |
1 01110 001 | -9/16 | 1 0110 0010 | -9/16 |
0 10110 101 | 208 | 0 1110 1010 | 208 |
1 00111 110 | -7/1024 | 1 0000 0111 | -7/1024 |
0 00000 101 | 2^(-11)*5 | 0 0000 0001 | 2^(-10) |
1 11011 000 | -2^12 | 1 1110 1111 | 2^7*31/16 |
0 11000 100 | 2^4*3/2 | 0 1111 0000 | +无穷 |
2.92
typedef unsigned float_bits; float_bits float_negate(float_bits x) { unsigned exp = (x>>23)&0xff; unsigned frac = x&0x7fffff; if((exp ==0xff)&&(frac!=0) ) return x; else return x^0x80000000; }
最高位取反即可
2.96
int float_f2i(float_bits x) { unsigned sign =x>>31; unsigned exp = (x>>23)&0xff; unsigned frac = x&0x7fffff; unsigned bias = 0x7F; int int_x; unsigned E; unsigned M; if(exp>=0 &&(exp<bias)) int_x = 0; // x less than 1 ,than convert it to 0 else if((exp-bias)>=31) int_x = 0x80000000; else { E = exp - bias ; M = frac | 0x800000; if (E > 23) { int_x = M << (E - 23); } else { int_x= M >> (23 - E); } } return sign? -int_x:int_x; }