家庭作业汇总

第二章家庭作业    2.59和2.66

2.59  编写一个C表达式,使它生成一个字,由x的最低有效字节和y的剩下的字节组成。对于运算数x=0x89ABCDEF和y=0x76543210,就得到0x76432EF。

答:(x&0xFF)|(y&~0xFF)

     验证:

          

 

2.66  写出代码实现如下函数:

        /*

         *Generate mask incicating leftmost 1in x.   Assume w=32.

         *For example 0xFF00 ->0x8000, and 0x6600 --> 0x4000.

         *If x=0,then return 0.

         */

       int leftmost_one(unsigned x);

       函数应该遵循位级整数编码规则,不过你可以假设数据类型int有w=32位。

       你的代码最多只能抱憾15个算术运算、位运算和逻辑运算。

       提示:先将x转换成形如[0...011...1]的位置。

 

答:我根据提示想到利用或运算,将最高位的1或到比它低的每一位上,忽然想如果x就是10000000..该如何让每一位都为1。先是x右移1位再和原x进行或,变成1100000...,再让结果右移2位和原结果或,变成11110000...,最后到16位,变成11111111...。

     int leftmost_one(unsigned x){
         x |= (x >> 1);
         x |= (x >> 2);
         x |= (x >> 4);
         x |= (x >> 8);
         x |= (x >> 16);
        return x^(x>>1);
     }

 

 

 

第三章家庭作业    3.69和3.70

3.69

A:long trace(tree_ptr tp)
    {
        long ret = 0;
        while(tp != NULL)
        {
           ret = tp->val;
           tp = tp->left;
        }
        return ret;
    }

B:作用是从根一直遍历左子树,找到第一个没有左子树的节点的值。

 

3.70 

A:long traverse(tree_ptr tp)
    {
        long v = MAX_LONG;
        if(tp != NULL)
       {
          v = min(traverse(tp->left), traverse(tp->right)); //Line16 cmovle: if(r12<rax) rax=r12;

          v = min(v, tp->v); //Line20 cmovle: if(rax>rbx) rax=rbx;
       }
       return v;
   }

B:找到树的所有节点的值中最小的一个。

 

 

第六章家庭作业  6.31

6.31

 

解答:

A. 高速缓存大小C=E*B*S=4*4*8=128 字节

B.

 

 

第八章家庭作业   8.19

因为Fork函数被调用一次,但是会返回两次:一次在调用进程(父进程)中(fork返回子进程的PID),一次在新创建的子进程中(fork返回0)。

所以调用Fork函数n次,就会产生2的n次方个进程。即总共会输出2^n行。

 

第十一章家庭作业   11.7

11.7  拓展TINY,使它可以提供MPG视频文件。用一个真正的浏览器来检验你的工作。

答:在get_filetype函数里面添加:

else if(strstr(filename, ".mpg") || strstr(filename, ".mp4"))
     strcpy(filetype, "video/mpg"); 

源代码:

#include "csapp.h"

void doit(int fd);
void read_requesthdrs(rio_t *rp);
int parse_uri(char *uri, char *filename, char *cgiargs);
void serve_static(int fd, char *filename, int filesize);
void get_filetype(char *filename, char *filetype);
void serve_dynamic(int fd, char *filename, char *cgiargs);
void clienterror(int fd, char *cause, char *errnum,
                char *shorting,char *longmsg);

int main(int argc,char *argv[])
{
    int listenfd,connfd,port,clientlen;
    struct sockaddr_in clientaddr;

    if(argc != 2)
    {
        fprintf(stderr,"usage: %s <port>\n",argv[0]);
        exit(0);
    }

    port = atoi(argv[1]);

    listenfd = Open_listenfd(port);
    while(1)
    {
        clientlen = sizeof(clientaddr);
        connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen);
        doit(connfd);
        Close(connfd);
    }
}
void doit(int fd)
{
    int is_static;
    struct stat sbuf;
    char buf[MAXLINE], method[MAXLINE],uri[MAXLINE],version[MAXLINE];
    char filename[MAXLINE],cgiargs[MAXLINE];
    rio_t rio;

    /*read request line and headers*/
    Rio_readinitb(&rio, fd);
    Rio_readlineb(&rio, buf, MAXLINE);
    sscanf(buf, "%s %s %s", method, uri, version);
    if(strcasecmp(method,"GET"))
    {
        clienterror(fd, method, "501","Not Implemented",
            "Tiny does not implement this method");
        return;
    }
    read_requesthdrs(&rio);

    /*prase URI from GET request*/
    is_static = parse_uri(uri, filename, cgiargs);
    if(stat(filename, &sbuf) < 0)
    {
        clienterror(fd, filename, "404","Not Found",
            "Tiny couldn't find this file");
        return;
    }
    if(is_static)//server static content
    {
        if(!(S_ISREG(sbuf.st_mode) || !(S_IRUSR & sbuf.st_mode)))
        {
            clienterror(fd, filename, "403","Forbidden",
                "Tiny couldn't read the file");
            return;
        }
        serve_static(fd, filename, sbuf.st_size);
    }
    else//server dynamic content
    {
        if(!(S_ISREG(sbuf.st_mode) || !(S_IXUSR & sbuf.st_mode)))
        {
            clienterror(fd, filename, "403","Forbidden",
                "Tiny couldn't run the CGI program");
            return;
        }
        serve_dynamic(fd, filename, cgiargs);   
    }
}
void clienterror(int fd, char *cause, char *errnum,
                char *shortmsg, char *longmsg)
{
    char buf[MAXLINE], body[MAXBUF];

    /*Build the HTTP response body*/
    sprintf(body, "<html><title>Tiny Error</title>");
    sprintf(body, "%s<body bgcolor=""ffffff"">\r\n",body);
    sprintf(body, "%s%s: %s\r\n",body,errnum,shortmsg);
    sprintf(body, "%s<p>%s: %s\r\n", body, longmsg, cause);
    sprintf(body, "%s<hr><em>The Tiny Web Server</em><>\r\n",body);

    /*Print the HTTP response*/
    sprintf(buf, "HTTP/1.0 %s %s\r\n",errnum, shortmsg);
    Rio_writen(fd, buf, strlen(buf));
    sprintf(buf, "Content-type: text/html\r\n");
    Rio_writen(fd, buf, strlen(buf));
    sprintf(buf, "Content-length: %d\r\n\r\n",(int)strlen(body));
    Rio_writen(fd, buf, strlen(buf));
    Rio_writen(fd, body, strlen(body));
}
//read_requesthdrs()来跳过请求报头的信息,直到遇见表示报头结束的空文本行。

void read_requesthdrs(rio_t *rp)
{
    char buf[MAXLINE];

    Rio_readlineb(rp, buf, MAXLINE);
    while(strcmp(buf, "\r\n"))
    {
        Rio_readlineb(rp, buf, MAXLINE);
        printf("%s", buf);
    }
    return;
}

int parse_uri(char *uri, char *filename, char *cgiargs)
{
    char *ptr;

    if(!strstr(uri, "cgi-bin"))//static content
    {
        strcpy(cgiargs, "");
        strcpy(filename, ".");
        strcat(filename, uri);
        if(uri[strlen(uri)-1] == '/')
            strcat(uri, "home.html");
        return 1;
    }
    else
    {
        ptr = index(uri, '?');
        if(ptr)
        {
            strcpy(cgiargs, ptr+1);
            *ptr = '\0';
        }
        else
            strcpy(cgiargs, "");
        strcpy(filename, ".");
        strcat(filename, uri);
        return 0;
    }
}

void serve_static(int fd, char *filename, int filesize)
{
    int srcfd;
    char *srcp, filetype[MAXLINE], buf[MAXBUF];

    /*Send response headers to client*/
    get_filetype(filename,filetype);
    sprintf(buf, "HTTP/1.0 200 OK\r\n");
    sprintf(buf, "%sServer: Tiny Web Server\r\n", buf);
    sprintf(buf, "%sContent-lenght: %d\r\n", buf, filesize);
    sprintf(buf, "%sContent-type: %s\r\n\r\n", buf, filetype);
    Rio_writen(fd, buf, strlen(buf));
    /*Send response body to client*/
    srcfd = Open(filename, O_RDONLY, 0);
    srcp = Mmap(0, filesize, PROT_READ, MAP_PRIVATE,srcfd,0);
    close(srcfd);
    Rio_writen(fd, srcp, filesize);
    Munmap(srcp, filesize);
}

void get_filetype(char *filename, char *filetype)
{
    if(strstr(filename, ".html"))
        strcpy(filetype, "text/html");
    else if(strstr(filename, ".gif"))
        strcpy(filetype, "image/gif");
    else if(strstr(filename, ".jpg"))
        strcpy(filetype, "image/jpeg");
    else 
        strcpy(filetype, "text/plain");
}

void serve_dynamic(int fd, char *filename, char *cgiargs)
{
    char buf[MAXLINE], *emptylist[]={NULL};

    /*Return first part of HTTP response*/
    sprintf(buf, "HTTP/1.0 200 OK\r\n");
    Rio_writen(fd, buf,strlen(buf));
    sprintf(buf, "Server: Tiny Web Server\r\n");
    Rio_writen(fd, buf,strlen(buf));

    if(Fork()==0)
    {
        setenv("QUERY_STRING", cgiargs, 1);
        Dup2(fd, STDOUT_FILENO);
        Execve(filename, emptylist,environ);
    }
    Wait(NULL);
}
posted on 2015-10-19 18:44  20135318刘浩晨  阅读(537)  评论(0编辑  收藏  举报