zoukankan      html  css  js  c++  java
  • sizeof运算符介绍以及常见的坑

    一、基本概念

    sizeof是C语言的关键字,它用来计算变量(或数据类型)在当前系统中占用内存的字节数。

    sizeof不是函数,产生这样的疑问是因为sizeof的书写确实有点像函数,sizeof有两种写法:

    用于数据类型

      sizeof(数据类型);
    

    数据类型必须用括号括住。 

      printf("字符型变量占用的内存是=%d
    ",sizeof(char));   // 输出:字符型变量占用的内存是=1
      printf("整型变量占用的内存是=%d
    ",sizeof(int));   // 输出:整型变量占用的内存是=4
    

    用于变量

      sizeof(变量名);
      sizeof 变量名;
    

    变量名可以不用括号括住,带括号的用法更普遍,大多数程序员采用这种形式。 

      int ii;
      printf("ii占用的内存是=%d
    ",sizeof(ii));   // 输出:ii占用的内存是=4
      printf("ii占用的内存是=%d
    ",sizeof ii);   // 输出:ii占用的内存是=4
    

    二、注意事项

    1、sizeof(结构体)

    理论上讲结构体的各个成员在内存中是连续存放的,和数组非常类似,但是,结构体占用内存的总大小不一定等于全部成员变量占用内存大小之和。在编译器的具体实现中,为了提高内存寻址的效率,各个成员之间可能会存在缝隙。用sizeof可以得到结构体占用内容在总大小,sizeof(结构体名)或sizeof(结构体变量名)都可以。

    示例(book90.c)

    /*
     * 程序名:book90.c,此程序用于演示C语言的结构体占用内存的情况
     * 作者:C语言技术网(www.freecplus.net) 日期:20190525
    */
    #include <stdio.h>
    
    // #pragma pack(1)  # 告诉编器内存按1字节对齐。
    
    struct st_girl
    {
      char name[50];     // 姓名
      int  age;          // 年龄
      int  height;       // 身高,单位:厘米cm
      char sc[30];       // 身材,火辣;普通;飞机场。
      char yz[30];       // 颜值,漂亮;一般;歪瓜裂枣。
    };
    
    int main()
    {
      struct st_girl queen;
      printf("sizeof(struct st_girl) %d
    ",sizeof(struct st_girl));
      printf("sizeof(queen) %d
    ",sizeof(queen));
    }
    

    运行效果
    在这里插入图片描述

    从上面的示例可以看出,struct st_girl全部成员变量占用的内存是50+4+4+30+30=118,但是结构体占用的内存是120。

    注意,C语言提供了结构体成员内存对齐的方法,可以使结构体成员变量之间的内存没有空隙,启用#pragma pack(1)代码即可。

    2、不要对void使用sizeof

      printf("sizeof(void)=%d
    ",sizeof(void));  // 输出sizeof(void)=1
    

    以上代码在有些编译器中可能无法通过。

    void是无值型或空类型,不知道存储空间大小的类型,编译器也不能确定它的大小。void不能声明变量,以下代码编译无法通过:

      void vv;
    

    但是以下代码是正确的:

      void *pv;
      printf("sizeof(void*)=%d
    ",sizeof(pv));   // 输出sizeof(void)=8
    

    pv是一个void指针,在64位操作系统中,指针变量占用的内存的大小都是8,下同。

    3、不要在子函数中对字符指针用sizeof

    如果把一个字符串(如char strname[21])的地址传给子函数,子函数用一个字符指针(如char *pstr)来存放传入的字符串的地址,如果在子函数中用sizeof(pstr),得到的不是字符串占用内存的字节数,而是字符指针变量占用内存的字节数(8字节)。

    所以,不能在子函数中对传入的字符串进行初始化,除非字符串的长度也作为参数传入到了子函数中。

    4、不要在子函数中对结构体指针用sizeof

    如果把一个结构体(如struct st_girl stgirl)的地址传给子函数,子函数用一个结构体指针(如struct st_girl *pgril)来存放传入的结构体的地址,如果在子函数中用sizeof(pgirl),得到的不是结构体占用内存的字节数,而是结构体指针变量占用内存的字节数(8字节)。正确的用法是用sizeof(struct st_girl)。

    三、版权声明

    C语言技术网原创文章,转载请说明文章的来源、作者和原文的链接。

    来源:C语言技术网(www.freecplus.net

    作者:码农有道

    如果这篇文章对您有帮助,请点赞支持,或在您的博客中转发我的文章,谢谢!!!

  • 相关阅读:
    leetcode -- Multiply Strings
    leetcode -- Merge Sorted Array
    leetcode -- Partition List
    leetcode -- Maximal Rectangle
    leetcode -- Largest Rectangle in Histogram TODO O(N)
    FFMPEG学习----分离视音频里的PCM数据
    FFMPEG 实现 YUV,RGB各种图像原始数据之间的转换(swscale)
    cmd 重定向
    使用FFMPEG类库分离出多媒体文件中的H.264码流
    FFMPEG学习----使用SDL构建视频播放器
  • 原文地址:https://www.cnblogs.com/wucongzhou/p/12660237.html
Copyright © 2011-2022 走看看