• cs:app 第二章homework(已完结)


    主要完成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.hif(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;
    }
  • 相关阅读:
    Redis-Sentinel 哨兵
    virtualenv and virtualenvwrapper
    C/C++中extern关键字详解
    C++ 中文拼音排序方法。
    vector排序
    VS2013 Ctrl+Shift+F 没反应
    PostMessage 解析
    CTextUI 文本控件 显示数字方法
    SetTimer API函数
    CEditUI 控件使用
  • 原文地址:https://www.cnblogs.com/blairwaldorf/p/7604376.html
Copyright © 2020-2023  润新知