hac*_*cks 61 c c++ arrays memset twos-complement
该联机帮助页说memset:
Run Code Online (Sandbox Code Playgroud)#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));
Run Code Online (Sandbox Code Playgroud)
它是因为int由4个字节(比如说)表示,并且一个不能得到数组中整数的所需值a.
但我经常看到程序员 memset用来将int数组元素设置为0或者-1.
int a[10];
int b[10];
memset(a, 0, sizeof(a));
memset(b, -1, sizeof(b));
Run Code Online (Sandbox Code Playgroud)
根据我的理解,使用整数初始化0是可以的,因为0可以用1个字节表示(在这种情况下可能是我错了).但是,如何可以初始化b与-1(一个4个字节的值)?
das*_*ght 69
奇怪的是,这个工作-1的原因与使用零的原因完全相同:在二进制补码二进制表示中,无论整数的大小如何,-1都1在其所有位中都有s,因此填充一个填充了字节的区域所有1s 在两个补码硬件上产生一个带-1符号ints,longs和shorts 的区域.
在与二进制补码不同的硬件上,结果会有所不同.的-1整数常数将被转换成一个unsigned char全部为,因为标准是特定的转换必须如何进行.但是,1根据平台的规则,将其所有位设置为的字节区域将被解释为整数值.例如,在符号和大小的硬件上,数组的所有元素都将包含相应类型的最小负值.
0,其值也为0。但是,如果所有位1值是-1。如果我们写入int a[2],则会分配4x2字节的内存,其中包含随机/垃圾位-
00110000 00100101 11100011 11110010 11110101 10001001 00111000 00010001
Run Code Online (Sandbox Code Playgroud)
然后,我们写memset(a, 0, sizeof(a)). 现在,memset()逐字节工作,0 的一字节表示 ( unsigned char)是. 于是,就变成——00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
Run Code Online (Sandbox Code Playgroud)
因此,a[0]和a[1]都初始化为0。
现在,让我们看看memset(a, -1, sizeof(a)):-1 的一个字节是11111111. 而且,我们得到——
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111
Run Code Online (Sandbox Code Playgroud)
在这里,a[0]和a[1]都将具有值-1。
但是,对于memset(a, 1, sizeof(a)):一个字节中的1是00000001-
00000001 00000001 00000001 00000001 00000001 00000001 00000001 00000001
Run Code Online (Sandbox Code Playgroud)
因此,该值将是- 16843009。