一生一芯系列笔记: 预学习——复习C语言(练习32笔记)

暮雨٩(๑˃̵ᴗ˂̵๑)۶终将落下 发布于 2024-12-27 1071 次阅读


为什么要将这个练习分开

我之前的笔记都是聚合在一篇文章的,但是因为后面几个问题比较难,而且会遇见各种各样的环境问题,所以这里将练习笔记分开,同时记录一下按照教程存在的一些问题。

简介

双向链表是一种比较重要的数据结构,在大部分学习C语言的教程中都有介绍,由于我是直接跳到32问的,所以无法直接按照教程内的步骤操作。这里我将介绍我完成这个工作的步骤。

构建框架

在《笨办法学C》中,作者搭建了一个简易的工程框架,将文件分布在了./bin、./build、./src、./tests等文件夹,并使用了在之前的part创建的minunit项目,对链表进行了简单的测试。

创建文件夹

在当前的工程目录下创建文件夹

mkdir bin/  build/ src/  tests/
cd src
mkdir lcthw

分别创建下述文件

cd lcthw
touch dbg.h list.c list.h
cd ../../tests/
touch dbg.h list_tesst.c minunit.h runtests.sh
cd ..
touch LICENSE Makefile

编写代码

我这里主要是对makefile做出了调整。由于在使用git时,为了方便gitignore文件识别编译得到的库文件和可执行文件,所以我们给可执行文件加上.out后缀。
在某些环境下,库文件必须写在.c文件的后面,cc在.c文件中读取到了函数后,会将这些函数名记下来,然后在后面的库文件中寻找函数定义。如果库文件在前,cc在读取到库文件后,会认为没有c文件使用这些函数,就不会记下这些函数,但是后面又在处理c文件时找不到。如下

 cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG build/libYOUR_LIBRARY.a tests/list_tests.c -ldl -o tests/list_tests.out
/usr/bin/ld: /tmp/cchVG058.o: in function `test_create':
/home/fengqi/Documents/GitRepos/ysyx/pre-study_phase/2024_12_18/Q32/tests/list_tests.c:12: undefined reference to `List_create'
/usr/bin/ld: /tmp/cchVG058.o: in function `test_destroy':
/home/fengqi/Documents/GitRepos/ysyx/pre-study_phase/2024_12_18/Q32/tests/list_tests.c:20: undefined reference to `List_clear_destroy'
/usr/bin/ld: /tmp/cchVG058.o: in function `test_push_pop':
/home/fengqi/Documents/GitRepos/ysyx/pre-study_phase/2024_12_18/Q32/tests/list_tests.c:27: undefined reference to `List_push'
/usr/bin/ld: /home/fengqi/Documents/GitRepos/ysyx/pre-study_phase/2024_12_18/Q32/tests/list_tests.c:30: undefined reference to `List_push'
/usr/bin/ld: /home/fengqi/Documents/GitRepos/ysyx/pre-study_phase/2024_12_18/Q32/tests/list_tests.c:33: undefined reference to `List_push'
/usr/bin/ld: /home/fengqi/Documents/GitRepos/ysyx/pre-study_phase/2024_12_18/Q32/tests/list_tests.c:37: undefined reference to `List_pop'
/usr/bin/ld: /home/fengqi/Documents/GitRepos/ysyx/pre-study_phase/2024_12_18/Q32/tests/list_tests.c:40: undefined reference to `List_pop'
/usr/bin/ld: /home/fengqi/Documents/GitRepos/ysyx/pre-study_phase/2024_12_18/Q32/tests/list_tests.c:43: undefined reference to `List_pop'
/usr/bin/ld: /tmp/cchVG058.o: in function `test_unshift':
/home/fengqi/Documents/GitRepos/ysyx/pre-study_phase/2024_12_18/Q32/tests/list_tests.c:52: undefined reference to `List_unshift'
/usr/bin/ld: /home/fengqi/Documents/GitRepos/ysyx/pre-study_phase/2024_12_18/Q32/tests/list_tests.c:55: undefined reference to `List_unshift'
/usr/bin/ld: /home/fengqi/Documents/GitRepos/ysyx/pre-study_phase/2024_12_18/Q32/tests/list_tests.c:58: undefined reference to `List_unshift'
/usr/bin/ld: /tmp/cchVG058.o: in function `test_remove':
/home/fengqi/Documents/GitRepos/ysyx/pre-study_phase/2024_12_18/Q32/tests/list_tests.c:70: undefined reference to `List_remove'
/usr/bin/ld: /tmp/cchVG058.o: in function `test_shift':
/home/fengqi/Documents/GitRepos/ysyx/pre-study_phase/2024_12_18/Q32/tests/list_tests.c:83: undefined reference to `List_shift'
/usr/bin/ld: /home/fengqi/Documents/GitRepos/ysyx/pre-study_phase/2024_12_18/Q32/tests/list_tests.c:86: undefined reference to `List_shift'
/usr/bin/ld: /tmp/cchVG058.o: in function `test_destroy':
/home/fengqi/Documents/GitRepos/ysyx/pre-study_phase/2024_12_18/Q32/tests/list_tests.c:20: undefined reference to `List_clear_destroy'
collect2: error: ld returned 1 exit status

所以我们调整原有的makefile文件,增添对tests的单独处理,如下

.PHONY: tests
$(TESTS): %: %.c $(TARGET)
    $(CC) $(CFLAGS) $< -o $@.out $(TARGET) $(LIBS)
tests: $(TESTS)
    sh ./tests/runtests.sh

同时我们也要编写自己的测试脚本runtests.sh

#!/bin/sh
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
cd "$SCRIPT_DIR"
./list_tests.out

测试

运行make,得到如下的输出

 make clean
rm -rf build src/lcthw/list.o tests/list_tests
rm -f tests/tests.log
find . -name "*.gc*" -exec rm {} \;
find . -name "*.out*" -exec rm {} \;
rm -rf `find . -name "*.dSYM" -print`
 make
cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG  -fPIC   -c -o src/lcthw/list.o src/lcthw/list.c
ar rcs build/libYOUR_LIBRARY.a src/lcthw/list.o
ranlib build/libYOUR_LIBRARY.a
cc -shared -o build/libYOUR_LIBRARY.so src/lcthw/list.o
cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG  tests/list_tests.c -o tests/list_tests.out build/libYOUR_LIBRARY.a -ldl 
sh ./tests/runtests.sh
DEBUG tests/list_tests.c:107:----- RUNNING: ./list_tests.out
----
RUNNING: ./list_tests.out
DEBUG tests/list_tests.c:97:
----- test_create
DEBUG tests/list_tests.c:98:
----- test_push_pop
DEBUG tests/list_tests.c:99:
----- test_unshift
DEBUG tests/list_tests.c:100:
----- test_remove
DEBUG tests/list_tests.c:101:
----- test_shift
DEBUG tests/list_tests.c:102:
----- test_destroy
ALL TESTS PASSED
Tests run: 6

工程文件

最后附上本文的工程文件

1735266014-Q32