You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何C语言中memset函数的第二个参数类型为int而非char?

关于C语言memset函数的疑问

函数手册说明

memset()函数将指针s指向的内存区域的前n个字节填充为常量字节c。

memset的函数签名:

void *memset(void *s, int c, size_t n);

核心疑问

  • 既然该函数是填充内存的前n个字节,为何参数c的类型是int而非char?用char类型难道不能正常工作吗?
  • 若传入的c数值超过一个字节的大小会发生什么?

测试代码与输出

为验证问题编写的测试代码:

#include <string.h>
#include <stdio.h>

int
main(int argc, char *argv[]) {

        char* s[5] = {0, 0, 0, 0, 0};
        memset((void*)s, 257, 5);
        for (int i=0; i<5; i++)
                fprintf(stdout, " %d", s[i]);
        putc('\n', stdout);
        return 0;
}

编译运行后的输出:

[amirreza@localhost memst]$ gcc memst.c 
[amirreza@localhost memst]$ ./a.out 
 16843009 0 0 0 0

问题解答

1. 参数c为何是int类型

这是C语言早期的历史设计遗留:在C的早期版本中,所有小于int的类型(如char、short)作为函数参数传递时,都会被自动提升为int类型。如果memset将c定义为char,调用时传入的char值依然会被转成int,所以直接把参数定义为int,既符合参数提升规则,也避免了额外的类型转换说明,同时保持了接口的一致性。

用char类型本身可以正常工作,但不符合C的参数传递习惯,且标准库接口已经沿用该定义至今。

2. 传入超过一个字节的c值的行为

根据C标准,memset会先将参数c转换为unsigned char,仅保留其**低8位(单字节)**的值,再用这个字节填充目标内存区域。比如传入的257(二进制100000001),最终会被处理为1(低8位00000001)。

3. 测试输出的解释

你定义的char* s[5]是一个指针数组,在32位系统中每个指针元素占4字节。调用memset(s, 257, 5)时,会把数组的前5个字节填充为1(257的低8位值):

  • 第一个指针元素的4个字节被全部填充为0x01,即0x01010101,转换成十进制就是16843009;
  • 第5个字节属于第二个指针元素,但仅填充了1个字节,剩下的3个字节仍为初始的0,所以第二个及以后的指针元素值还是0,这就对应了你看到的输出结果。

内容的提问来源于stack exchange,提问作者Amir reza Riahi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 05:42:33