我正在学习 Zed Shaw 的 Learn C the Hard Way。我对 ex34 中函数定义的代码感到困惑。在 ex34 中,Zed 教我们如何实现动态数组。darray.h 中的代码:
typedef struct DArray {
int end;
int max;
size_t element_size;
size_t expand_rate; /* it's 300 by default. */
void **contents;
} DArray;
DArray *DArray_create(size_t element_size, size_t initial_max);
int DArray_expand(DArray *array);
/* other operations... */
让我感到困惑的代码在 darray.c 中:
DArray *DArray_create(size_t element_size, size_t initial_max)
{
DArray *array = malloc(sizeof(DArray));
array->max = initial_max;
array->contents = calloc(initial_max, sizeof(void *));
array->end = 0;
array->element_size = element_size;
array->expand_rate = DEFAULT_EXPAND_RATE; /* defined in header, which is 300 */
return array;
}
static inline int DArray_resize(DArray *array, size_t newsize)
{
array->max = newsize;
void *contents = realloc(array->contents, array->max * sizeof(void *));
array->contents = contents;
return 0;
}
int DArray_expand(DArray *array)
{
size_t old_max = array->max;
DArray_resize(array, array->max + array->expand_rate);
memset(array->contents + old_max, 0, array->expand_rate + 1); // confused
return 0;
}
/* Definitions of other operations... */
memset
所以我的问题是,为什么被调用的第三个参数DArray_expand
是array->expand_rate + 1
而不是array->expand_rate
?我认为扩展后的数组长度为 400(假设初始长度为 100),范围从contents[0]
到contents[399]
. 需要初始化的元素范围从contents[100]
到contents[399]
,那么 的第三个参数memset
应该array->expand_rate
是 300。谁能给我解释一下?
感谢您编辑我的帖子。我忘了我可以使用内联代码 md 语法。
编辑:我也对在这段代码中使用 memset 感到困惑。我电脑中 memset 的手册页说:
memset() 函数将值 c(转换为无符号字符)的 len 个字节写入字节串 b。
我用谷歌搜索了 memset 的实现。我从这个链接得到这个:
#include <stddef.h> /* size_t */
void *memset(void *s, int c, size_t n)
{
unsigned char* p=s;
while(n--)
*p++ = (unsigned char)c; // This line confused me..
return s;
}
在我的操作系统(达尔文 12.0.0)中,sizeof(void *)
和的sizeof(int *)
值为 8。我尝试了更多。我的操作系统中各种指针的大小似乎是8。如果指针的大小是8,那么这段代码会发生什么:
*p++ = (unsigned char)c; /* the value of c is 0. size of
unsigned char is 1 in my OS */
如果 Zed 的代码有错误,你能告诉我如何修复它吗?