• 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用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化为' '或'';
                单个字符串数组以及数组的话,比较直接 char a[100];memset(a,'',sizeof a);(注意哦这里真的可以不打括号)
                对于结构体的话,我觉得不实用,略;
    • memset要注意的是数组用来初始化别的整数,最好不要这个样子来搞,比较容易出事;
        例如:(这里注意一下,不要直接使用sizeof a)
    #include <cstring>
    #include <iostream>
    using namespace std;
    #define INF 0x3f3f3f3f
    int main(){
         char a[10] = { "1234567" };
         printf("%s ", a);
         memset(a, 'd', 5*sizeof(char));
         printf("%s ", 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就不怕。
  • 相关阅读:
    Intel Code Challenge Elimination Round (Div.1 + Div.2, combined) C. Destroying Array -- 逆向思维
    一种压缩图片的方法---Machine learning 之 K-Means
    【Codeforces】Codeforces Round #374 (Div. 2) -- C. Journey (DP)
    strcpy自实现
    Coursera公开课-Machine_learing:编程作业6
    【Codeforces】Codeforces Round #373 (Div. 2) -C
    【Codeforces】Codeforces Round #373 (Div. 2)
    【Leetcode】376. Wiggle Subsequence
    Coursera公开课-Machine_learing:编程作业5
    C++实现日期类(Date类)
  • 原文地址:https://www.cnblogs.com/zengguoqiang/p/9606864.html
Copyright © 2020-2023  润新知