manpage中关于memset
的说明:
很明显,
#include <string.h> void *memset(void *s, int c, size_t n)
The
memset()
function fills the firstn
bytes of the memory area pointed to bys
with the constant bytec
.
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
初始化为-1
(一个4字节的值)呢?
0
进行初始化的原因有些错误。这样做是可以的,因为0
适合于unsigned char
(所以在作为memset
的第二个参数时不会被截断),并且因为sizeof(int)
字节零的位模式与sizeof(int)
个一字节零的位模式相同。这两个条件必须同时满足才能起作用。实际上,在二进制补码算术中,只有两个数字符合这些条件:0
和-1
。 - zwolint
类型的值x的位与一个sizeof(int)
个unsigned char
类型的值相同,且这些unsigned char
类型的值都等于x,那么它就适用于x。此外,我们必须将值为x的unsigned char
视为从x转换而来,因为-1无法表示。如果是这样的话,那么0和-1并不是唯一的这样的值。16,843,009 • x适用于任何整数0 ≤ x < 256。(16,843,009是十六进制1010101)。 - Eric Postpischilmemset
的第二个参数的内部截断。我认为这是作弊,因为如果不考虑与传统 C 的向后兼容性,memset
将采用unsigned char
第二个参数。 - zwolmemset
需要一个int
,将其转换为unsigned char
,并将其复制到每个字节中。-1不能表示为“unsigned char”;它会被转换为UCHAR_MAX
。因此,如果您允许,那么0x34343434
(或类似值,对于更大的字节C实现)将以同样的方式工作。 - Eric Postpischilmemset
是基于unsigned char
定义的。在发布的问题或C规范中不存在signed char
或char
。 - Eric Postpischil