2018/08/23 cstring中memset()函数的运用
好多东西其实以前已经查过了,然后当时理解的还行,可是过段时间没用有些又会忘记,然后又去找资料又查,浪费了不少的时间和精力,所以,我,曾国强,今天起,要好好做笔记了!
今天复习第一个知识点,为什么要叫复习呢?!
void *memset(void *buffer,int c,int count) 包含于头文件 #include <cstring>
buffer:为指针或是数组,c是赋予buffer的值,count是buffer的长度。
作用是在一段内存块中填充某个给定的值,它对较大的结构体或者数组进行清零操作的一种最快的的方法;
这个函数本质上是用来给字符赋初值的,所以它每次赋值是一个一个字节的赋值,也就是说int c中 c 的范围是:[-128,127]
- memset用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化为' '或'\0';
单个字符串数组以及数组的话,比较直接 char a[100];memset(a,'\0',sizeof a);(注意哦这里真的可以不打括号)
对于结构体的话,我觉得不实用,略;
- memset要注意的是数组用来初始化别的整数,最好不要这个样子来搞,比较容易出事;
例如:(这里注意一下,不要直接使用sizeof a)
#include <cstring>
#include <iostream>
using namespace std;
#define INF 0x3f3f3f3f
int main(){
char a[10] = { "1234567" };
printf("%s\n", a);
memset(a, 'd', 5*sizeof(char));
printf("%s\n", a);
return 0;
}
运行输出
1234567
ddddd67
请按任意键继续. . .
假如类型变成int呢?(这里就可以使用我舒服的sizeof a了);
#include <cstring>
#include <iostream>
using namespace std;
int main(){
int a[5] = { 100 };
for (int i = 0; i < 5; i++){
cout << a[i] << " ";
}cout << endl;
memset(a, 1, sizeof a);
for (int i = 0; i < 5; i++){
cout << a[i] << " ";
}cout << endl;
return 0;
}
运行输出如下
100 0 0 0 0
16843009 16843009 16843009 16843009 16843009
请按任意键继续. . .
至于为什么不是1呢??因为memset赋值是按一个字节来进行赋值,而整形是四个字节!!
所以用来赋值最大的时候,结合0x3f3f3f3f; 简直爽的不要不要;
上面写的简直是一坨屎,当时都忘了一个字节多大;今天延续昨天晚上由一个常数加LL引发的命案;现在说到了常数赋值操作。
- 对于常用0和-1赋初始值的直接运用
先来讲这个函数为什么能直接的对0和-1进行赋初始值操作,前面说到memset是按一个字节来进行赋值的,所以0我们很好理解
int 是32位,其二进制是 0000 0000 0000 0000 0000 0000 0000 0000 (四个字节),其中取尾端的一个字节来对int的四个字节来进行赋值;
很明显的看到起结果还是 0000 0000 0000 0000 0000 0000 0000 0000;那我们再来看-1;这里就有点问题了,-1(int)的二进制是 1000
0000 0000 0000 0000 0000 0000 0001;按照刚刚讲的来的话岂不是赋值完之后就应该成 0000 0001 0000 0001 0000 0001 0000 0001?
这样子就不是-1了啊!别着急,这里就要讲到很重要的一点,由于计算机底层当中,数据存放的方式是补码,所以我们这里还需要将它转化为二进制补码:1111 1111 1111 1111 1111 1111 1111 1111 ;那在按刚刚的来是不是就没有错了啊。
回忆刚刚我们讲到了一个细节,为什么是从尾部的一个字节拿过来进行赋值呢?这一点我们实践一下就知道了 ,整个这样的数不就行了吗
0000 1000 0000 0100 0000 0010 0000 0001;是不是很妙啊哈哈哈哈,用计算器得到这个数为262657,运行一下
是不是就得到了验证;
- 对于赋最大值的思考
int 是32位的,所有它的最大值的话就应该是 0111 1111 1111 1111 1111 1111 1111 1111,这个结果十进制2 147 483 647,十六进制0x7FFFFFFF;看这个数的尾部是不是和-1有点像?没错,要是用这个赋初值,那你就死定了,就赋成-1了!之前一直不能理解为什么好多人喜欢去用#define INF 0x3f3f3f3f 然后memset(a,INF,sizeof a);这样子的话,这个值也不如0x7f7f7f7f这个这么大啊;
假如说单独的赋值,我们当然说用0x7fffffff作为最大值最好,但是用到了memset()函数,我们会认为0x7f7f7f7f比较好,但是我们还需要考虑一下另外的问题,无穷大也是有性质的,无穷加无穷还是等于无穷,如果我们用0x7ffffffff和0x7f7f7f7f的话,一加就溢出了!所有对于ACM做题的话,还是比较推荐使用0x3f3f3f3f来作为最大值。最小值类似就不讲了
还有注意到一个问题memset()似乎有点懒惰性,long long 这个类型的赋值,只会给前七个字节赋值,第八个字节是亏待过你吗?
平时总是会碰到溢出的情况,在这里贴一下int 的范围:[-2147483648,2147483647] em..1e10就不怕
long long de fanwei : [-9223372036854775808,9223372036854775807] em.. 1e19就不怕。