zoukankan      html  css  js  c++  java
  • 9、内存操作

      在实际项目设计中,内存操作随处可见,本文这里就重点将内存相关的操作符进行讲解和区分。

    1、sizeof的用法

      sizeof一般有以下两种用法:

    第一种用法:

    sizeof(type_name);//sizeof(类型名)

    类型名称包括基本类型,也包括构造类型,如;

    sizeof(int)、sizeof(U16)、sizeof(MATH_CUBE_ST)

    第二种用法:

    sizeof(var_obj_name);//sizeof(变量对象名称

    如:

    int val;
    u32 u32len;
    MATH_CUBE_ST stCube;
    sizeof(val)      ; sizeof(u32len);sizeof(stCube);

    在实际编程中,这两种方法都是可以的,但是一般建议用第二张种方法,以memset来举例,memset用来给指定地址的内存段指定相同的值,通常用来初始化变量,一般用法如下:

    MATH_CUBE_ST stCube;
    memset(&stCube,0,sizeof(MATH_CUBE_ST));
    //将变量stCube全部清零

    这样写没有问题,但是每个人写程序时,后面都会用到复制粘贴,英雌我们复制时还要先去找定义行,然后进行复制,之后还要在找函数进行复制粘贴,如果两者距离很长的话,这样做明显是浪费时间且容易出错的,这是,第二种方法的好处就体现出来了,即:

    memset(&stCube,0,sizeof(stCube));

    这样问题就可以避免了。

    2、sizeof的几个特例

      1)、使用sizeof计算数组的大小及元素的个数

        sizeof是在编译时进行计算的,因此可以将sizeof当作常量来对待,使用sizeof可以方便的计算数组所占用的内存大小,也可以计算元素的个数,在计算元素个数是,需要使用除法,示例如下:

    /**********************************************************
    *        内容:测试sizeof函数计算数组大小
    *        说明:无
    *        日期:2017.11.1
    *        版本:v1.0
    ************************************************************/
    #include <stdio.h>
    #include <string.h>
    
    unsigned int au32val[] = { 1,2,3,4,5 };
    int main()
    {
        //输出数组au32val占用的字节数,4*5=20
        printf("array  length  is  %d
        ", sizeof(au32val));
        //输出数组au32val的元素个数,5
        printf("array element is  %d
    ", sizeof(au32val) / sizeof(unsigned int));
        return;
    
    }

    输出结果如下:

    2)、使用sizeof计算新参数组

        看如下示例:

    /**********************************************************
    *        内容:使用sizeof计算新参数组
    *        说明:无
    *        日期:2017.11.1
    *        版本:v1.0
    ************************************************************/
    #include <stdio.h>
    #include <string.h>
    
    int main(char abstract[3])
    {
        printf("para len is %d
    ", sizeof(abstract));
        return;
    }

     

    这里的结果并不是3,而是4,这里函数参数acStr已经不再是数组了,而是蜕变为了指针,相当于char *acStr,这里是因为数组是传“址”的,调用者只需将实参的地址传过去即可,所以acStr为指针类型(char*),程序结果输出也就是4;

    (这里也引出了一个编程中的习惯,一般情况下是不要使用数组作为函数的参数,而是使用指针,如果要再想直到数组的长度,还需要添加一个长度的形参过来。

    3)、字符串指针常量和数组字符串中的sizeof

      先看示例如下:

    /**********************************************************
    *        内容:字符串指针常量和数组字符串中的sizeof
    *        说明:无
    *        日期:2017.11.1
    *        版本:v1.0
    ************************************************************/
    #include <stdio.h>
    #include <string.h>
    
    int main()
    {
        char* pcpointStr = "123456789";
        char acArrayStr[] = "123456789";
        //输出字符串指针长度
        printf("sizeof(pcpointStr)=%d
    ", sizeof(pcpointStr));
        //输出字符串指针指向内容的长度,结果为1
        printf("sizeof(*pcpointStr)=%d
    ", sizeof(*pcpointStr));
        //输出数组的长度,记过为10,系统自动加结束符
        printf("sizeof(acArrayStr)=%d
    ", sizeof(acArrayStr));
        //输出指针指向的变量长度,结果为1
        printf("sizeof(*acArrayStr)=%d
    ", sizeof(*acArrayStr));
        return;
    }

     

      通过上述示例可以看出指针和数组使用sizeof的区别,出现这样的区别的原因是,sizeof是在编译器直接计算出来的,其次是因为sizeof是计算的内存的大小,字符串指针的类型就是字符串指针类型,所以不管字符串的长度是多少,指针类型的长度都是4个字节,而数组字符串在sizeof下认为是数组类型,而数组类型编译时已经分配了大小,所以返回的为实际大小。

      因此,无论是获取字符串指针指向内容还是字符串数组中的字符串长度,都应该用库函数strlen,而不是用sizeof;

    2、memset和memcpy

    1)、memset   

      在之前讲解sizeof时,我们已经用到过memset函数,这里将对其进行详细讲解和示例分析。其函数原型如下所示:

    void *memset(void *dest, int  c, size_t  counter);

    memset函数的作用是将缓存设定为一个专门的字符,对照函数原型,就是将已经开辟内存空间dest的首count个字节的值设定为c。

    示例如下:

    /**********************************************************
    *        内容:测试memset函数
    *        说明:无
    *        日期:2017.11.1
    *        版本:v1.0
    ************************************************************/
    #include <stdio.h>
    #include <string.h>
    
    int main()
    {
        char TestStr[] = "AAAAAAAAAAAAA";
        printf("The original string is :%s
    ", TestStr);
        memset(TestStr, 'C', 3);//将TestStr的前三个字符替换成C
        printf("the change string is :%s
    ", TestStr);
        return 0;
    }

    结果为:

    2)memcpy

       函数原型如下

    void *memcpy(void *dest,const    void  *src,    size_t count);

     memcpy函数的作用是在缓存之间复制字符,对照函数原型,memcpy即用来复制src所指向的内存内容的前count个字节到dest所指的内存地址上。

    示例如下:

    /**********************************************************
    *        内容:测试memcpy函数
    *        说明:无
    *        日期:2017.11.1
    *        版本:v1.0
    ************************************************************/
    #include <stdio.h>
    #include <string.h>
    typedef signed char INT8;//重定义数据类型
    typedef signed int INT32;
    
    
    int main()
    {
        char szTestStr[100] = "AAAAAAAAAAAAA";
        char szCopyStr[100] = "HELOWORLD";
        printf("The original string is :%s
    ", szTestStr);
        memcpy(szTestStr, szCopyStr+2, 3);//将TestStr的前三个字符替换成从szCopy第3个字符开始三个字符
        printf("the change string is :%s
    ", szTestStr);
        return 0;
    }

     

    值得注意的是:src与dest所指向的内容不能叠加,函数返回值为指向dest的指针。

    在实际项目中,两者经常同时使用,即先用memset初始化某数组或结构体,然后用memcpy将内容复制到被初始化的变量中。

    char szStringContent[1024] = { 0 };
    ......
    memset(szStringContent, 0x00, sizeof(szStringContent));
    memcpy(szStringContent, "li", strlen("li"));
    ......

     

  • 相关阅读:
    Voiceover “眼里” 的HTML5标签
    Edge浏览器默认地址被百度劫持
    How to fix "ReferenceError: primordials is not defined" error
    php 读文件
    jsconfig.json: Unexpected token ] in JSON at position
    公司入域电脑更新遇到 0x8024401c 解决办法
    颜色计算
    Terminal 美化
    highcharts 查看配置
    cra
  • 原文地址:https://www.cnblogs.com/noticeable/p/7843274.html
Copyright © 2011-2022 走看看