manpage说memset
:
#include <string.h> void *memset(void *s, int c, size_t n)
memset()
函数使用常量字节n
填充s
指向的内存区域的第一个c
字节。
很明显memset
不能用于初始化int
数组,如下所示:
int a[10];
memset(a, 1, sizeof(a));
这是因为int
由4个字节(比方说)表示,而且无法获得数组a
中整数的所需值。
但我经常看到程序员使用memset
将int
数组元素设置为0
或-1
。
int a[10];
int b[10];
memset(a, 0, sizeof(a));
memset(b, -1, sizeof(b));
根据我的理解,使用整数0
进行初始化是正常的,因为0
可以用1个字节表示(在这种情况下可能是我错了)。但是如何用b
(4字节值)初始化-1
?
答案 0 :(得分:69)
奇怪的是,这与-1
一起使用的原因与使用零的原因完全相同:在two's complement binary representation中,-1
的所有内容都为1
位,无论整数的大小如何,因此填充一个填充了所有1
s的字节的区域会产生-1
符号int
s,long
s的区域,和short
s在两个补充硬件上。
在不同于两个补码的硬件上,结果会有所不同。 -1
整数常量将转换为所有1的unsigned char
,因为该标准特定于必须如何执行转换。但是,根据平台的规则,将其所有位设置为1
的字节区域将被解释为整数值。例如,在符号和大小的硬件上,数组的所有元素都将包含相应类型的最小负值。
答案 1 :(得分:2)
0
时,其值也为 0 。但是,如果所有位都是 1
,则值为 -1 。
当我们写int a[2]
时,会分配 4x2 字节的内存,其中包含随机/垃圾位-
00110000 00100101 11100011 11110010 11110101 10001001 00111000 00010001
然后我们写memset(a, 0, sizeof(a))
。现在,memset()
不能区分int
和char
。它按字节逐个工作。 0 的一个字节表示形式是00000000
。因此,我们得到-
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
因此,a[0]
和a[1]
均用 0 初始化。
现在,让我们来看看memset(a, -1, sizeof(a))
: -1 的一个字节是11111111
。而且,我们得到-
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111
此处,a[0]
和a[1]
的值都为 -1 。
但是,对于memset(a, 1, sizeof(a))
:一个字节中的 1 是00000001
-
00000001 00000001 00000001 00000001 00000001 00000001 00000001 00000001
因此,该值为- 16843009 。