memset作为最常用的函数之一,在我阅读多方资料之后,对其有了新的了解。
有一次我在使用memset对int数组进行赋值的过程中遇到了以下问题
#include<stdio.h>
#include<string.h>
int main(){
int k[100];
memset( k , 1 , sizeof(k) );
printf("%d",k[0]);
}
在我刚开始的认知中,我认为会输出 1,而实际上却出现了以下问题
16843009
--------------------------------
Process exited after 0.03809 seconds with return value 0
经过后续资料的查询,阅读一些博客,发现了问题所在,我们常用memset对数组进行赋值,但memset函数缺来自于"string.h"函数库,本是为char数组服务的函数运用于int或者其他类型的数组的时候,便产生了问题。
我们可以使用代码
#include<stdio.h>
#include<string.h>
int main(){
char k[100];
memset( k , 'a' , 50 );
printf("%c",k[99]);
}
将k[0] -> k[49]赋值为 'a',而之后char则为空。
同样,当我们利用一下代码进行运算时
#include<stdio.h>
#include<string.h>
int main(){
int k[100];
memset( k , 0 , 100 );
printf("%d\n",k[24]);
printf("%d",k[25]);
}
得到了一下结果
0
13
--------------------------------
Process exited after 0.01968 seconds with return value 0
memset的第三个参数为100的时候,并未像char数组一样将0-99的100个数据赋值,实际上只赋值了0-24即25个。即int赋值的数据量为char的四分之一,我想你已经猜到了问题所在
char占用1个字节而int占用了四个字节
我们继续推广,一个字节占用了8个bit,一个bit代表一个数字,而计算机是使用二进制进行存储,所以我们可以将一个char在计算机中的存储视为 00000000 -> 11111111,将11111111转为十进制我们可以得到255,我们也可以解释到为什么ASCLL码表只有0-255个字符。
回到主题,我们利用char数组的存储方式推广到int数组的存储方式,也就是四个char数据
整整一共32个字符,当这32个字符写满1的时候(第一位作为符号位不写),我们得到了一个数字
恰巧这就是int的最大值。
理解了int的存储方式之后,我们可以解决关于memset的赋值问题了,我们memset一个int数组为1的时候,事实上计算机只是像char一样每一个B写入了一个1,如图。
得到了与文章开头相同的结果,也就是16,843,009。
可在很多算法题的答案中,经常使用memset对于int数组进行赋值,为什么不出错呢?
如果我们memset( a , 0 , sizeof( a ) );计算机将每一位都写为0,最终结果自然也为0,所以没有出错。
同样进过计算,我们可以发现,如果将四个B全部写入一个数据不会对其结果值发生改变的,我们也可以照常使用,例如0,-1。
=========================================================================
同样我们会发现在算法题中,经常用#defind INF 0x3f3f3f3f定义一个无穷大值。并用memset( a , INF , sizeof( a ) );进行初始化
计算发现,这是一个大于8bit的值,但memset同样进行了赋值。
我们尝试使用大于8bit的值对int数组进行赋值发现
#include<stdio.h>
#include<string.h>
#define INF 0x3F3F3F3E
int main(){
int k[100];
memset( k , INF , sizeof( k ) );
printf("%d\n", k[0] );
}
得到结果
1044266558
--------------------------------
Process exited after 0.03518 seconds with return value 0
将该值转化为2进制可以发现
当一个数据大于8bit的时候,memset函数取了该数据的后8bit对数组进行了赋值。
同样进行推广,我们可以得到两个常用值对数组赋值极大极小
max: 0x3F3F3F3F
min:0x80
所以当我们用非特殊值对数组进行赋值的时候,需要利用for循环完成。