memset是一个经常被用来初始化数组的函数,其定义如下:
1
|
void * memset ( void * ptr, int value, size_t num ); |
它的效果大致是把以ptr为起始地址,长度为num个字节的内存区间内,每个字节的值都设值成value。
这里就有一个奇怪的现象了,为什么value的类型被声明成了int,但却只用到了最低位的那个字节?或者说为什么memset只需要一个字节的值来做填充,但却需要用户传入一个int?
这还要从C89标准说起,据说在C89标准出来之前,C的代码中并不强制函数原型的声明,如果一个函数的调用出现在了它的声明之前,编译器会去假设一个声明。比如说:
1
2
3
4
5
6
7
|
void bar() { int a = foo(5); } int foo( int x) { return x + 1; } |
在这段代码中,foo在bar中被调用,但是声明却在其之后,现在的编译器是会给出编译错误的,但是在C89之前,编译器会根据函数调用的语句,int a = foo(5)来猜出foo的函数原型,比如传入的值是5,就是一个int,返回值也是一个int。
所以说,在一些古老的代码中,memset的调用可以发生在它被声明之前。但在C89之后,函数声明变成了必须的,于是memset就一定要被先声明出来,这时候为了照顾已有的代码,如
1
|
void * memset ( array, 0, sizeof (array) ); |
即使是对char数组赋值的memset,如
1
|
void * memset ( array, 'a' , sizeof (array) ); |
字符常量(如’a')在C语言中也被认为成int类型,于是memset的原型就只能也使用int了……
就是说,它在接受‘a’类型的字符时,实际上的类型是int
reference:
http://stackoverflow.com/questions/5919735/why-does-memset-take-an-int-instead-of-a-char
https://leonax.net/p/3037/why-memset-takes-int-as-its-second-parameter-instead-of-char/