使用教材
《“笨办法” 学C语言(Learn C The Hard Way)》
https://www.jianshu.com/p/b0631208a794
-
完整源码 :
liblcthw
- 源文件路径
单元测试文件:liblcthw/tests/darray_tests.c
头文件 :liblcthw/src/lcthw/darray.h
实现 :liblcthw/src/lcthw/darray.c
代码运行
- 查看文件目录结构
ls -R
liblcthw$ ls -R
.:
bin LICENSE Makefile README.md src tests
./bin:
./src:
lcthw
./src/lcthw:
darray.c darray.h dbg.h
- 执行
make
liblcthw$ make
(. . . 略 . . .)
Running unit tests:
----
RUNNING: ./tests/darray_tests
ALL TESTS PASSED
Tests run: 8
tests/darray_tests PASS
- 全部单元测试通过后 再次查看文件结构
ls -R
liblcthw$ ls -R
.:
bin build LICENSE Makefile README.md src tests
./bin:
./build:
liblcthw.a liblcthw.so
./src:
lcthw
./src/lcthw:
darray.c darray.h darray.o dbg.h
./tests:
darray_tests darray_tests.c minunit.h runtests.sh tests.log
代码说明
- 动态数组,是一个
void **
指针的数组 - 动态数组
DArray
typedef struct DArray {
int end;
int max;
size_t element_size;
size_t expand_rate;
void **contents;
} DArray;
- 关于
static inline
如果你要创建一个宏的代码块,而你又不需要代码生成,那么你就可以使用一个
static inline
函数
static inline void *DArray_get(DArray * array, int i)
{
check(i < array->max, "darray attempt to get past max");
return array->contents[i];
error:
return NULL;
}
- 动态数组,创建
DArray *DArray_create(size_t element_size, size_t initial_max)
{
DArray *array = malloc(sizeof(DArray));
check_mem(array);
array->max = initial_max;
check(array->max > 0, "You must set an initial_max > 0");
array->contents = calloc(initial_max, sizeof(void *));
check_mem(array->contents);
array->end = 0;
array->element_size = element_size;
array->expand_rate = DEFAULT_EXPAND_RATE;
return array;
error:
if(array) {
if(array->contents) free(array->contents);
free(array);
}
return NULL;
}
为结构体申请内存 :DArray *array = malloc(sizeof(DArray));
array->contents = calloc(initial_max, sizeof(void *));
- 单元测试:测试DArray_create函数
char *test_create()
{
array = DArray_create(sizeof(int), 100);
mu_assert(array != NULL, "DArray_create failed.");
mu_assert(array->contents != NULL, "contents are wrong in darray");
mu_assert(array->end == 0, "end isn't at the right spot");
mu_assert(array->element_size == sizeof(int),
"element size is wrong.");
mu_assert(array->max == 100, "wrong max length on initial size");
return NULL;
}
- 动态数组,调整大小
static inline int DArray_resize(DArray * array, size_t newsize)
{
array->max = newsize;
check(array->max > 0, "The newsize must be > 0.");
void *contents = realloc(array->contents, array->max * sizeof(void *));
// check contents and assume realloc doesn't harm the original on error
check_mem(contents);
array->contents = contents;
return 0;
error:
return -1;
}
void *contents = realloc(array->contents, array->max * sizeof(void *));
malloc calloc realloc
https://zh.cppreference.com/w/c/memory/malloc
malloc
定义于头文件<stdlib.h>
void* malloc( size_t size );
size
- 要分配的字节数
成功时,返回指向新分配内存的指针。为避免内存泄漏,必须用 free() 或 realloc() 解分配返回的指针。
失败时,返回空指针。
https://zh.cppreference.com/w/c/memory/calloc
calloc
定义于头文件<stdlib.h>
void* calloc( size_t num, size_t size );
num
- 对象数目
size
- 每个对象的大小
成功时,返回指向新分配内存的指针。为避免内存泄漏,必须用 free() 或 realloc() 解分配返回的指针。
失败时,返回空指针。
https://zh.cppreference.com/w/c/memory/realloc
realloc
定义于头文件<stdlib.h>
void *realloc( void *ptr, size_t new_size );
ptr
- 指向需要重新分配的内存区域的指针
new_size
- 数组的新大小(字节数)
成功时,返回指向新分配内存的指针。返回的指针必须用 free() 或 realloc() 归还。原指针 ptr 被非法化,而且任何通过它的访问是未定义行为(即使重分配是就地的)。
失败时,返回空指针。原指针 ptr 保持有效,并需要通过 free() 或 realloc() 归还。
网友评论