memset函数的正确类型是什么?如何按手册定义实现自定义memset?
如何按标准手册定义实现memset函数?
我自己重写memset函数时,一旦解引用void指针或者让第二个参数和第一个参数类型不同就会报错,所以我把函数改成了这样:
void ft_memset(unsigned char *st, unsigned char c, size_t n)
想问下能不能按照手册里的标准定义来实现这个函数?手册里的版本是:
void *memset(void *s, int c, size_t n) // 这是手册中的版本
约束条件:
- 仅使用
stdio.h库来引入size_t - 编译时必须添加
-Wall -Wextra -Werror参数
我的现有代码如下:
#include <stdio.h> // stdio.h to use size_t; // void *ft_memset(unsigned char *str, unsigned char c, size_t n) { unsigned int i; i = 0; while (i < n) { str[i] = c; i++; } return(str); }
当然可以按照标准定义实现,核心是通过类型转换解决void指针解引用和参数类型不匹配的问题,具体修改如下:
修改后的符合标准的代码
#include <stdio.h> void *ft_memset(void *s, int c, size_t n) { unsigned char *ptr = (unsigned char *)s; unsigned char uc = (unsigned char)c; size_t i = 0; while (i < n) { ptr[i] = uc; i++; } return s; }
关键修改说明
- 匹配标准参数定义:将函数参数改为
void *s和int c,完全对齐手册中的memset签名 - 合法处理void指针:把
void *s强制转换为unsigned char *,这是标准允许的操作,因为memset本质是按字节填充内存,无符号字符类型能准确对应单字节操作 - 处理int类型的填充值:将
int c转换为unsigned char,符合memset的标准行为——仅使用c的低8位作为填充字节 - 消除类型匹配警告:把循环变量
i的类型从unsigned int改为size_t,避免和size_t n比较时出现类型不匹配,在-Wall -Wextra -Werror编译参数下不会触发警告 - 返回原指针:直接返回传入的
void *s,符合memset返回指向原内存区域指针的要求
这样修改后,编译时加上指定参数也不会报错,完全实现了手册定义的memset功能。
内容的提问来源于stack exchange,提问作者Sofía Huppertz
相关产品推荐
相关产品推荐

