Lab0 C Programming Lab(CMU)(CSAPP深入理解计算机系统)

目录

实验下载地址

大致要求

大致操作

自动打分具体操作

代码和大致思路

queue.h中两个结构体

queue.c中的几个函数

Free queue的函数

两个insert函数:

Remove函数

Return Size函数:

Reverse函数

Auto Grade分数


实验下载地址

15-213/14-513/15-513: Introduction to Computer Systems / Schedule Fall 2021Introduction to Computer Systems; Schedulehttp://www.cs.cmu.edu/afs/cs/academic/class/15213-s22/www/schedule.html

大致要求

1.Linux命令行基础

2.C语言基础

3.数据结构基础(链表基本操作)

4.基本英语阅读能力

大致操作

下载.tar 文件,解压后对着README操作即可;

简单来说,允许直接修改的文件只有 queue.h和queue.c,打代码的时候打开这两个就够了,其他的鼓励查看学习;

按照要求修改后,保存;

在linux终端输入命令进行测试打分。

自动打分具体操作

(在所在路径下操作)

ccc@ccc-virtual-machine:~/桌面/CSAPP/Lab/Lab0 CProgramming Lab/cprogramminglab-h
andout$ make format
clang-format -style=file -i queue.c queue.h

make format:直接make可能会返回一个跟clang-format有关的报错

make:编译文件并产生自动测试文件

make test:测试正确性

这里的报错方式是valgrind,可以连带着大致学习一下

代码和大致思路

用中文写注释会报错(QAQ)

queue.h中两个结构体

/************** Data structure declarations ****************/

/**
 * @brief Linked list element containing a string.
 *
 * You shouldn't change this struct.
 */
typedef struct list_ele {
    /**
     * @brief Pointer to a char array containing a string value.
     *
     * The memory for this string should be explicitly allocated and freed
     * whenever an element is inserted and removed from the queue.
     */
    char *value;

    /**
     * @brief Pointer to the next element in the linked list.
     */
    struct list_ele *next;
} list_ele_t;

/**
 * @brief Queue structure representing a list of elements
 */
typedef struct {
    /**
     * @brief Pointer to the first element in the queue, or NULL if the
     *        queue is empty.
     */
    size_t size;
    list_ele_t *tail;
    list_ele_t *head;
    /*
     * TODO: You will need to add more fields to this structure
     *       to efficiently implement q_size and q_insert_tail
     */
} queue_t;

这里可以看到cmu给的注释还是比较详细的

queue.c中的几个函数

创建新queue:

/**
 * @brief Allocates a new queue
 * @return The new queue, or NULL if memory allocation failed
 */
queue_t *queue_new(void) {
    queue_t *q = malloc(sizeof(queue_t));
    if (q != NULL)
    /* What if malloc returned NULL? */
    {
        q->head = NULL;
        q->tail = NULL;
        q->size = 0;
    }
    return q;
}

Free queue的函数

/**
 * @brief Frees all memory used by a queue
 * @param[in] q The queue to free
 */
void queue_free(queue_t *q) {
    /* How about freeing the list elements and the strings? */
    if (q != NULL) {
        while (q->head != NULL) {
            /*Free all the space*/
            // for (size_t i = 0; i < q->size; i++) {
            /*I think they're the same.*/
            list_ele_t *temp;
            temp = q->head;
            q->head = temp->next;
   
            free(temp->value);
            /*Array in structs are not freed with structs being freed.*/

            free(temp);
        }
        /* Free queue structure */
        free(q);
    }
}

两个insert函数:

拿到文件时已有的代码后面有注释:already there

/**
 * @brief Attempts to insert an element at head of a queue
 *
 * This function explicitly allocates space to create a copy of `s`.
 * The inserted element points to a copy of `s`, instead of `s` itself.
 *
 * @param[in] q The queue to insert into
 * @param[in] s String to be copied and inserted into the queue
 *
 * @return true if insertion was successful
 * @return false if q is NULL, or memory allocation failed
 */
bool queue_insert_head(queue_t *q, const char *s) {
    list_ele_t *newh; // already there.
    if (!q)
        return false;
    /* What should you do if the q is NULL? */

    newh = (list_ele_t *)malloc(sizeof(list_ele_t)); // alreadythere
    if (!newh)
        return false;
    char *stemp;

    /* Don't forget to allocate space for the string and copy it */
    if (s) {
        stemp = (char *)malloc((strlen(s) + 1) * sizeof(char));
        if (!stemp) {
            free(newh);
            return false;
        }
        strcpy(stemp, s);
    } else
        stemp = NULL;
    /* What if either call to malloc returns NULL? */

    newh->value = stemp;

    newh->next = q->head; // already there.
    q->head = newh;       // already there.
    if (q->tail == NULL)  //(q->size == 0)     // means q->size==0
        q->tail = q->head;
    q->size++;

    return true; // already there.
}

/**
 * @brief Attempts to insert an element at tail of a queue
 *
 * This function explicitly allocates space to create a copy of `s`.
 * The inserted element points to a copy of `s`, instead of `s` itself.
 *
 * @param[in] q The queue to insert into
 * @param[in] s String to be copied and inserted into the queue
 *
 * @return true if insertion was successful
 * @return false if q is NULL, or memory allocation failed
 */
bool queue_insert_tail(queue_t *q, const char *s) {
    if (!q)
        return false;
    list_ele_t *newh;

    newh = (list_ele_t *)malloc(sizeof(list_ele_t));
    if (!newh) {
        return false;
    }

    char *newc;

    if (s) {
        newc = (char *)malloc(sizeof(char) * (strlen(s) + 1));
        if (!newc) {
            free(newh);
            return false;
        }
        strcpy(newc, s);
    } else
        newc = NULL;

    newh->value = newc;

    newh->next = NULL;
    q->tail->next = newh;
    q->tail = newh;
    if (q->size == 0) {
        q->head = q->tail;
    }

    q->size++;
    return true;

    /* You need to write the complete code for this function */
    /* Remember: It should operate in O(1) time */
    // return false;//already there.
}

Remove函数

/**
 * @brief Attempts to remove an element from head of a queue
 *
 * If removal succeeds, this function frees all memory used by the
 * removed list element and its string value before returning.
 *
 * If removal succeeds and `buf` is non-NULL, this function copies up to
 * `bufsize - 1` characters from the removed string into `buf`, and writes
 * a null terminator '\0' after the copied string.
 *
 * @param[in]  q       The queue to remove from
 * @param[out] buf     Output buffer to write a string value into
 * @param[in]  bufsize Size of the buffer `buf` points to
 *
 * @return true if removal succeeded
 * @return false if q is NULL or empty
 */
bool queue_remove_head(queue_t *q, char *buf, size_t bufsize) {
    /* You need to fix up this code. */
    if (!q)
        return false;

    if (q->size == 0) // which means q->size==0
        return false;
    list_ele_t *newqt;
    newqt = q->head;

    q->head = newqt->next;
    q->size--;

    if (q->size == 0) {
        q->tail = NULL;
        // q->head = NULL;
    }
    if (buf) {
        // buf = newqt->value;
        // if (strlen(newqt->value) > bufsize - 1) {
        //     buf[bufsize - 1] = '\0';
        //     newqt->value = &buf[bufsize];
        //     // free(newqt->value);
        // }
        /*ERROR: AddressSanitizer: attempting free on
        address which was not malloc()-ed*/
        strncpy(buf, newqt->value, bufsize - 1);
        buf[bufsize - 1] = '\0'; ///
    }

    //if (newqt->value)
        free(newqt->value);
    free(newqt);

    return true;
}

Return Size函数:

/**
 * @brief Returns the number of elements in a queue
 *
 * This function runs in O(1) time.
 *
 * @param[in] q The queue to examine
 *
 * @return the number of elements in the queue, or
 *         0 if q is NULL or empty
 */
size_t queue_size(queue_t *q) {
    /* You need to write the code for this function */
    /* Remember: It should operate in O(1) time */
    if (!q)
        return 0;
    return q->size;
}

Reverse函数

(不让用allocate和free)

/**
 * @brief Reverse the elements in a queue
 *
 * This function does not allocate or free any list elements, i.e. it does
 * not call malloc or free, including inside helper functions. Instead, it
 * rearranges the existing elements of the queue.
 *
 * @param[in] q The queue to reverse
 */
void queue_reverse(queue_t *q) {
    list_ele_t *s;
    list_ele_t *temp;
    if (!q || q->size == 0 || q->size == 1)
        return;

    s = q->head;
    temp = s->next;

    while (temp) {
        s->next = temp->next;
        temp->next = q->head;
        q->head = temp;
        temp = s->next;
    }
    q->tail = s;
    /* You need to write the code for this function */
}

Auto Grade分数

ccc@ccc-virtual-machine:~/桌面/CSAPP/Lab/Lab0 CProgramming Lab/cprogramminglab-h
andout$ make test 
chmod +x driver.py
./driver.py
---	Trace		Points

+++ TESTING trace trace-01-ops:
./qtest -v 1 -f ./traces/trace-01-ops.cmd
# Test of insert_head and remove_head
---	trace-01-ops	6/6

+++ TESTING trace trace-02-ops:
./qtest -v 1 -f ./traces/trace-02-ops.cmd
# Test of insert_head, insert_tail, and remove_head
---	trace-02-ops	6/6

+++ TESTING trace trace-03-ops:
./qtest -v 1 -f ./traces/trace-03-ops.cmd
# Test of insert_head, insert_tail, reverse, and remove_head
---	trace-03-ops	6/6

+++ TESTING trace trace-04-ops:
./qtest -v 1 -f ./traces/trace-04-ops.cmd
# Test of insert_head, insert_tail, and size
---	trace-04-ops	6/6

+++ TESTING trace trace-05-ops:
./qtest -v 1 -f ./traces/trace-05-ops.cmd
# Test of insert_head, insert_tail, remove_head reverse, and size
---	trace-05-ops	6/6

+++ TESTING trace trace-06-string:
./qtest -v 1 -f ./traces/trace-06-string.cmd
# Test of truncated strings
---	trace-06-string	7/7

+++ TESTING trace trace-07-robust:
./qtest -v 1 -f ./traces/trace-07-robust.cmd
# Test operations on NULL queue
---	trace-07-robust	7/7

+++ TESTING trace trace-08-robust:
./qtest -v 1 -f ./traces/trace-08-robust.cmd
# Test operations on empty queue
---	trace-08-robust	7/7

+++ TESTING trace trace-09-robust:
./qtest -v 1 -f ./traces/trace-09-robust.cmd
# Test remove_head with NULL argument
---	trace-09-robust	7/7

+++ TESTING trace trace-10-malloc:
./qtest -v 1 -f ./traces/trace-10-malloc.cmd
# Test of malloc failure on new
---	trace-10-malloc	7/7

+++ TESTING trace trace-11-malloc:
./qtest -v 1 -f ./traces/trace-11-malloc.cmd
# Test of malloc failure on insert_head
---	trace-11-malloc	7/7

+++ TESTING trace trace-12-malloc:
./qtest -v 1 -f ./traces/trace-12-malloc.cmd
# Test of malloc failure on insert_tail
---	trace-12-malloc	7/7

+++ TESTING trace trace-13-perf:
./qtest -v 1 -f ./traces/trace-13-perf.cmd
# Test performance of insert_tail
---	trace-13-perf	7/7

+++ TESTING trace trace-14-perf:
./qtest -v 1 -f ./traces/trace-14-perf.cmd
# Test performance of size
---	trace-14-perf	7/7

+++ TESTING trace trace-15-perf:
./qtest -v 1 -f ./traces/trace-15-perf.cmd
# Test performance of insert_tail, size, and reverse
---	trace-15-perf	7/7
---	TOTAL		100/100

你可能感兴趣的:(c语言,数据结构,链表,linux)