memset如何以-1初始化整数数组

How memset initializes an array of integers by -1?

本文关键字:初始化 整数 数组 memset      更新时间:2023-10-16

手册说关于memset:

#include <string.h>
void *memset(void *s, int c, size_t n)

memset()函数用常数字节c填充s所指向的内存区域的第一个n 字节

很明显,memset不能用来初始化int数组,如下所示:

int a[10];
memset(a, 1, sizeof(a));  

这是因为int是由4个字节(例如)表示的,并且无法从数组a中获得所需的整数值。
但我经常看到程序员使用memsetint数组元素设置为0-1

int a[10];
int b[10];
memset(a, 0, sizeof(a));  
memset(b, -1, sizeof(b));  

根据我的理解,用整数0初始化是可以的,因为0可以用1字节表示(在这种情况下可能是我错了)。但是如何用-1(一个4字节的值)初始化b呢?

奇怪的是,这对-1起作用的原因与对零起作用的原因完全相同:在two的补码二进制表示中,-1的所有位都有1 s,无论整数的大小,因此用所有1 s填充的字节填充区域会产生一个-1区域,在two的补码硬件上有int s, long s和short s。

在不同于2的补码的硬件上,结果将不同。整型常量-1将被转换为所有整型常量中的unsigned char,因为标准特定于必须如何执行转换。但是,根据平台规则,所有位设置为1的字节区域将被解释为整数值。例如,在符号和大小硬件上,数组的所有元素都将包含相应类型的最小负值。

当一个数的所有位都为 0 时,其值也为0。但是,如果所有位都是 1 ,则值为-1

如果我们写int a[2]4x2字节的内存被分配,其中包含随机/垃圾位-

00110000 00100101 11100011 11110010    11110101 10001001 00111000 00010001

然后,我们写memset(a, 0, sizeof(a))。现在,memset()一个字节一个字节地工作,0的一个字节表示(unsigned char)是00000000。因此,它变成了-

00000000 00000000 00000000 00000000    00000000 00000000 00000000 00000000
因此,a[0]a[1]都初始化为0

现在让我们看看memset(a, -1, sizeof(a)): 的一个字节-111111111。得到-

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