精华内容
下载资源
问答
  • 一个结构体变量所占用的空间是
    千次阅读
    2019-05-26 14:16:14

    原文链接:https://www.cnblogs.com/lykbk/archive/2013/04/02/krtmbhrkhoirtj9468945.html

    结构体大小的计算 用最简单的方法,通俗易懂的方法计算结构体大小

    结构体计算要遵循字节对齐原则

    结构体默认的字节对齐一般满足三个准则:

    1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;

    2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);

    3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)

    其实 暂且不管这三原则,我的方法只要记住第三个,就是结构体大小结果要为成员中最大字节的整数倍

    先看下面定义的两个结构体.

    struct {   char a;   short b;   char c; }S1;

    struct {  char  a;  char  b;  short c; }S2;

    分别用程序测试得出sizeof(S1)=6 , sizeof(S2)=4

    注意 为什么 仅仅改变了结构体成员的顺序,结果不一样?

    解:

     

    (1)首先找出成员变量中最大的字节,可见对于S1和S2 最大是short ,占2个字节,

      (2)所以以后都已2个字节为准,也就是说最多只要2个字节,其他填充占位,注意下图一个格子表示一个字节,

        (3)所以先画2个格子,以后看成员顺序,逐次增加,每次一2为增加基准

        对于S1 ,来说,顺序是 char->short->char      

    2个字节
    第一个char占一个字节    多的这一个补0,只是占位作用
    short 刚好占2个字节 
    第二个char也占1个多的这一个补0

     

    所以对于S1结构体大小为 2*3=6,至于为什么第二个char,多的那个字节不丢到,就是遵循第三个原则,就是结构体大小结果要为成员中最大字节的整数倍

    对于S2 嘛,也画个图,但是顺序是 char->char->short

     

    第一个char占一个字节第二个char占一个字节
    short 刚好占2个字节 

    S2=2*2=4

     

    按照这个方法再看这样的一个结构体:

    struct stu1
             {
                   int i;
                                 char c;
                   int j;
             };

    很明显:最大字节为4个。顺序int  char int

     

    stu1
    intintintint
    char000
    第二个intintintint

    因为 int占4个,而char已经咱了一个,不够,所以那三个只能多余占位

    Stu1=3*4=12

    那么换一下呢?

    struct stu2
             {
                   int i;
                                
                   int j;

                char  c;
             };

    Stu2=3*4=12;

    再看一个:就是当结构体成员变量是另外一个结构体时,只要把结构体中成员为另一结构体作为整体相加就行

     

    typedef struct A
    {
    char a1;
    short int a2;
      int a3;
      double d;

    };

    A=16

    typedef struct B
    {
    long int b2;
    short int b1;
    A a;

    };

    而对于B,先不要管A a,也就是先去掉A a 成员结构体B 算得 其为8,所以最后结果为8+16=24;24才是最后结果

    更多相关内容
  • 结构体变量占用存储空间大小占用内存最大属性是score, 占8字节, 所以第次会分配8字节将第次分配的8字节分配给age4,分配给ch1, 还剩下
  • 原文链接:... 一个结构体变量占多大内存空间的问题   直接来看相同数据结构体的几种书写的格式吧。 格式一: 1. struct tagPhone  2. {  3. char A;  4. int B;  5. ...

    原文链接:http://blog.sina.com.cn/s/blog_75a2ecd20102xca0.html

    一个结构体变量占多大内存空间的问题

     

    直接来看相同数据结构体的几种书写的格式吧。

    格式一:

    1.  struct tagPhone    

    2.  {    

    3.       char   A;    

    4.       int    B;    

    5.       short  C;    

    6.  }Phone1;  

    格式二:  

    1.  struct tagPhone    

    2.  {    

    3.       char   A;    

    4.       short  C;    

    5.       int    B;    

    6.  }Phone2;   

    格式三:  

    1.  struct tagPhone3    

    2.  {    

    3.       char    A;    

    4.       char   B[2];    

    5.       char    C[4];    

    6.  }Phone3;   

    格式四:

    1.  struct tagPhone3    

    2.  {    

    3.       char    A;    

    4.       double  B[2];    

    5.       char    C[4];    

    6.  }Phone4;   

    例题:请问下面定义的结构体变量aa在计算机内存中占用多少字节?

    #include

    main()

    {

    struct  student

    {   float    height;

    short int  age ;

    char     sex ;

    }aa;

    printf("%d\n",sizeof(aa));  //屏幕上将显示多少?

    }

    错误解答:我们都知道,char类型占用1个字节,float型占用4个字节,short int类型占用2个字节,int型在VC6.0中占用4个字节(TC2.0中占用2个字节),long占用8个字节,double占用8个字节。因此,我们可能会犯一个错误就是直接4+2+1=7,结构体aa占用7个字节。这是错的。

    错误分析:计算结构体大小时需要考虑其内存布局,编译系统为了提高计算机访问数据的效率,在安排结构体每个成员的时候采用了内存对齐的方法,具体是:结构体在内存中的存放按单元进行存放,每个单元的大小取决于结构体中最大基本类型的大小

    对格式一:

    图1

    ​​​​因为所有成员中B成员类型最大(int型占用4个字节),故结构体Phone1在内存分布时以4字节为一个单元来存储每个成员。又因为A占用一个字节后,只剩下3字节了,放不下后面紧挨的成员B了,所以必须开辟一个新的单元来存放B,B刚好占满一个单元,接下来的成员C又必须再开辟一个新的单元来存放。这样,Phone1占用的字节数就是:3*4=12;

    同理对于格式二,

    图2

    A后面还有三个字节,足够存放C,所以C就放在了A的后面,然后只剩下一个字节了,不够存放后面的B,于是又开辟一个新单元存放B。这样,Phone2占用的内存字节就为2*4=8。

    对于格式三: 

     图3

    ​上面结构体中,最大数据类型是char,占一个字节,因此它的一个存储单元就是1个字节。sizeof(Phone3) =1 + 2 + 4 = 7, 其大小正好是结构体中各成员所占内存空间之和,这种情况也是最节省存储空间的。

    对于格式四:

    图4

    ​Phone4中最大的数据类型是double,占8个字节,因此它的一个存储单元就是8个字节。由上图可知sizeof(Phone4)=4*8=32。

    综上所述,格式一和格式四是非常浪费存储空间的,应该尽力避免;格式三对存储空间的利用率是最高的;格式二存储空间的利用率居中。作为一个优秀的程序员,应该深入掌握这些写法的差异性,以便视情况选用不同的写法。

    展开全文
  • 二、结构体所占总内存为其成员变量空间最大数据类型的整数倍。 本人使用的是x86平台,默认对齐系数为8,因此,综上述,我们可以对最开始那段代码进行分析。 #include #pragma pack(8) int main() { struct...

    首先,我们来看一下下面这段代码。

    #include <stdio.h>
    
    int main() 
    {
    	struct A{
    		char a;
    		int b;
    		double c;
    	}part1;
    	
    	struct B{
    		char a;
    		double b;
    		int c;
    	}part_one;
    	
    	printf("%d %d", sizeof(part1), sizeof(part_one));
    	
    	return 0;
    }
    

    我们不妨假设这两个结构体所占内存字节数为其包含的各个变量所占字节数的代数和,那么,运行结果应该是1 + 4 + 8 和 1 + 8 + 4,也就是13 13。但是,最终我们得到的运行结果却是这样子的:
    运行结果

    这就不得不提到计算机中存在的一种叫做内存对齐的机制了。

    • 什么是内存对齐呢?
      内存对齐的规则是这样子的(引用自百度百科):

    每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。程序员可以通过预编译命令#pragma pack(n),n=1,2,4,8,16来改变这一系数,其中的n就是你要指定的“对齐系数”。

    • 对齐规则:
    1. 数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员的对齐按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行。
    2. 结构(或联合)的整体对齐规则:在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行。
    3. 结合1、2可推断:当#pragma pack的n值等于或超过所有数据成员长度的时候,这个n值的大小将不产生任何效果。
      注:#pragma pack(n)是用于设定变量以n字节对齐方式对齐(即变量起始位置在内存空间中的偏移量是对齐系数的倍数)。

    另外,不得不提到的是,我们的计算机的对齐策略一般是这样子的:
    一、起始位置为成员数据类型所占内存的整数倍,若不足则不足部分用数据将内存填充为该数据类型的整数倍。
    二、结构体所占总内存为其成员变量中所占空间最大数据类型的整数倍。

    本人使用的是x86平台,默认对齐系数为8,因此,综上所述,我们可以对最开始那段代码进行分析。

    #include <stdio.h>
    #pragma pack(8)
    
    int main() 
    {
    	struct A{
    		char a;	//char型,1 < 8,按1对齐;起始offset为0 
    		int b;	//int型,4 < 8,按4对齐;因0被占用,起始offset为4 
    		double c;//double型,8 = 8,按8对齐;因0被占用,起始offset为8 
    	}part1;
    	
    	struct B{
    		char a;	//char型,1 < 8,按1对齐;起始offset为0
    		double b;//double型,8 = 8,按8对齐;因0被占用,起始offset为8
    		int c;	//int型,4 < 8,按4对齐;因0,4,8均已被占用,起始offset为16(4是被自动填充,为了保证数据存放) 
    	}part_one;
    	//对这段代码进行分析之后,我们不难发现其中存在一些"空洞",对于这些空洞,程序会自动补零
    	//于是,其最终结果是16和24也就不难理解了
    	
    	printf("%d %d", sizeof(part1), sizeof(part_one));
    	
    	return 0;
    }
    

    那么,这里又引起了一个新的问题,内存对齐机制是怎么来的呢?
    在计算机中通常会让CPU从内存中一次读取若干个字节的数据,而不是一次只读取一个字节的数据,这样的好处是提高了计算机的效率,然而坏处也显而易见。
    假设CPU一次从内存中读取四个字节的数据,而现在内存中存在一个char型的数据和一个int型的数据,如果内存不对齐,当CPU第一次跨越四个字节寻址找到了一个char型的数据,而此时CPU的指向到了int型的中间区域,导致这个int型变量未找到,然后CPU会返回去再次寻找,直到找到该int型变量。这样不但没能提高效率,反而增加了CPU的负担。因此我们通常会在第一个char型变量后边填充一部分数据来保证每次寻址时地址都是该数据的整数倍,这样就避免了上述“错误”的发生,也就是所谓的内存对齐。

    展开全文
  • C语言中结构体变量到底占多大空间

    千次阅读 2015-06-10 17:48:25
    结构体是C语言中

            很久之前就想将内存对齐这块儿知识点总结记录下来,无奈本人患有very very严重的拖拉症,直到今天才下决心将这件事儿解决掉,废话不多说了,开工!(ps:本人所用编译器version为 gcc Ubuntu4.9.2-10 ubuntu13 4.9.2)

            结构体到底占多大的空间呢?先看一下下面这道题的输出结果:

    #include<stdio.h>
    
    typedef struct test
    {
         char a;
         int   b;
         double c;
    }TEST;
    
    int main(void)
    {
         TEST test1;
         printf("%ld\n",sizeof(test1));
         
         return 0;
    }

     
    

           不妨大胆猜想,结构体所占空间是不是其成员所占空间的代数和呢??按照这个猜想,该题的答案应该为13,然而事实却让人大跌眼镜,本题输出的结果为16。google一下知这是因为计算机中存在一种叫做内存对齐的机制导致了该结果的发生。

           在计算机中通常会让CPU从内存中一次读取若干个字节的数据,而不是一次只读取一个字节的数据,这样的好处是提高了计算机的效率,然而坏处也显而易见。

           假设CPU一次从内存中读取四个字节的数据,而现在内存中存在一个char型的数据和一个int型的数据,如果内存不对齐,当CPU第一次跨越四个字节寻址找到了一个char型的数据,而此时CPU的指向到了int型的中间区域,导致这个int型变量未找到,然后CPU会返回去再次寻找,直到找到该int型变量。这样不但没能提高效率,反而增加了CPU的负担。因此我们通常会在第一个char型变量后边填充一部分数据来保证每次寻址时地址都是该数据的整数倍,这样就避免了上述“错误”的发生,也就是所谓的内存对齐。

           内存对齐的规则很简单:

           一、起始位置为成员数据类型所占内存的整数倍,若不足则不足部分用数据将内存填充为该数据类型的整数倍。

           二、结构体所占总内存为其成员变量中所占空间最大数据类型的整数倍。

           假设上题中结构体变量是从零号内存开始存储,则char型变量占一个字节,而后int型变量发现起始位置在一号内存处,并不满足起始位置为int型所占4字节整数倍的要求,故将一二三号内存填充满,从四号内存处开始存储该int型成员,当该int型成员存储完成后已经用了八个字节的空间,因此此时double型成员的起始位置为第八号内存,满足第一条条件,所以double型开始存储,存储完成后该结构体变量刚好占16个字节,刚好是最大数据类型double八个字节的整数倍,所以存储完成,因此该结构体变量占了16个字节。

    再看这一题

    #include<stdio.h>
    
    typedef struct test
    {
         char a;
         double   b;
         int c;
    }TEST;
    
    int main(void)
    {
         TEST test1;
         printf("%ld\n",sizeof(test1));
         
         return 0;
    }
           这题乍一看和上一题的区别仅仅是将int型和double型调换了位置,那结果呢?结果肯定是不一样的,按照上述分析步骤走一遍看看,先是char型从零号开始存储,因为要遵循第一条原则故double型从八号开始存储,一到七号被填充,double型存储完后int型从16号位置开始存储,存储完成后发现此时一共占了20个字节的空间,不满足第二条规则,因此又将20到23号位置填充,所以该结构体变量占24个字节,从这里就可以看出在定义结构体时成员变量的顺序会影响其在内存中所占的资源大小,因此我们在定义结构体时要调整顺序使其尽可能在内存中所占空间最小。

              其实内存对齐的规则和编译环境也是有一定的关系,其默认对齐系数也有差异,并且也是可以通过预处理命令#pragma pack(n)来改变的,这里所说的规则只是一个常见规则,不过话说回来万变不离其宗,其实本质都是一样的大笑大笑

    展开全文
  • 请问下面定义的结构体变量aa在计算机内存中占用多少字节? #include main() { struct student { float height; short int age ; char sex ; }aa; printf("%d\n",sizeof(aa)); //屏幕上将显示多少? } 错误解答:...
  • 1.下列程序中,结构体变量n占内存字节数是(答案为6?) union U {  char s[4];   int i;  long l; }; struct A {  int c;  union U u; }a; 2.若有下面的说明和定于: struct test {  int m1;...
  • 结构体变量

    千次阅读 2021-12-08 15:13:57
    结构体种集合,它里面包含了多个变量或数组,它们的类型可以相同,也可以不同,每这样的变量或数组都称为结构体的成员(Member)。 结构体也是种数据类型,它由程序员自己定义,可以包含多其他类型的数据...
  • 结构体变量是指将不同的数据类型整合成一个有机的整体,以便于调用。 struct Student { int num; char name[20]; int score; } Student stud1;//stud1就是结构体变量 结构体指针变量是指指向结构体变量的指针...
  • 在计算结构体大小时需要考虑其内存布局,结构体在内存中存放是按单元存放的,每单元多大取决于结构体中最大基本类型的大小,下面我们看几例子:1.struct A{char a;int b;short c;}str1;这里char占1字节,int占...
  • 将不同类型的数据组合成一个有机的整体即为结构体。结构体由许多组织在一起的数据项组成,这些数据项不需要属于同一类型。 2、结构体类型及结构体变量定义 (1)结构体类型声明 struct 结构体名 { 成员表列; }; ①–...
  • 转载自:http://blog.csdn.net/grantxx/article/details/7577730 转载自:...一个结构体变量定义完之后,其在内存中的存储并不等于其包含元素的宽度之和。 例一:
  • 在C语言中我们如何去运用结构体变量和结构的变量的指针作为函数的参数呢,其实我们对于结构体的变量是有一定的了解的,他们就是将一个结构体变量的值传递给另外一个函数,那么这种有三种方法,希望大家都能够了解...
  • 结构体变量才包含数据存储的空间; 2,结构体与数组相似但数组中的数据类型全部相同,结构体中的数据类型不一定相同; 3,结构体变量在内存中的位置关系(不考虑内存对齐的问题) #include struct Student { char s_...
  • 目录结构体结构体类型的定义结构体变量的定义1.先定义结构体类型,再定义结构体变量2.在定义结构体类型的同时定义结构体变量3.定义无名结构体类型变量结构体变量的初始化与赋值结构体成员的访问结构体的大小结构体的...
  • tianqixin结构体中成员变量分配的空间是按照成员变量占用空间最大的来作为分配单位,同样成员变量的存储空间也是不能跨分配单位的,如果当前的空间不足,则会存储到下一个分配单位中。#include typedef struct{...
  • 结构体 数组是用于保存组相同类型数据的, 而结构体是用于保存组不同类型数组的 在使用结构体之前必须先定义结构体类型, 因为C语言不知道你的...结构体变量占用存储空间大小 struct Person{ int age; // 4 第
  • 展开全部sizeof,一个其貌不扬的家伙,引无数菜鸟竟折腰,小虾我当初也没少犯62616964757a686964616fe78988e69d8331333264623331迷糊,秉着“辛苦我一个,幸福千万人”的伟大思想,我决定将其尽可能详细的总结一下。...
  • 结构体(struct)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存放在offset为该数据成员大小的的整数倍的地方(比如int在32位机器上为4字节,则要从四字节的整数倍开始存储)。考虑如下一段...
  • 显然,结构体变量中第一个成员的地址就是结构体变量的首地址。因此,第一个成员i的偏移量为0。第二个成员c的偏移量是第一个成员的偏移量加上第一个成员的大小(0+4),其值为4;第三个成员j的偏移量是第二个成员的...
  • 【C语言笔记】struct结构体变量的用法

    千次阅读 多人点赞 2020-09-14 09:10:26
    我们都知道C语言中变量的类型决定了变量存储占用空间。当我们要使用一个变量保存年龄时可以将其声明为int类型,当我们要使用一个变量保存某一科目的考试成绩时可以将其声明为float。 那么,当我们要做一个学生信息...
  • 结构体在内存中占用空间

    千次阅读 多人点赞 2018-06-03 16:54:32
    之前对结构占用内存一直很迷,下面就举例子,到底是按照哪个变量类型计算内存?应该怎样计算才是正确的呢? struct str { char a; int b; float b; double d; }; 这个结构体占用的内存是多少呢? 运行...
  • 定义结构体变量的三种方法

    万次阅读 多人点赞 2018-07-07 20:25:41
    1、先定义结构体类型再定义结构体变量如先定义结构体类型:struct student{ int StuNo;//学号 char StuName[20]; //学生姓名 char Sex; //学生性别 int Agel //年龄}再定义结构体变量: struct student stu1,stu...
  • 一个结构体变量定义完之后,其在内存中的存储并不等于其包含元素的宽度之和。 例一: #include <iostream> using namespace std; struct X {
  • 显然,结构体变量中第一个成员的地址就是结构体变量的首地址。因此,第一个成员i的偏移量为0。第二个成员c的偏移量是第一个成员的偏移量加上第一个成员的大小(0+4),其值为4;第三个成员j的偏移量是第二个成员的...
  • 如何定义结构体变量及如何使用

    千次阅读 2018-10-08 20:05:46
    虽然已经了解结构体类型,但是结构体类型变量的定义只有种方法么,这当然不是的,所以我把我知道的几种方法列出来供给大家参考一下;  首先是第种,也是我们经常用的种: 1 #include &lt;stdio...
  • 编译器在为结构体成员开辟空间时,首先检查预开辟空间的地址相对于结构体首地址的偏移量是否为对齐参数的整数倍,若是,则存放该成员;若不是,则填充若干字节,以达到整数倍的要求。这句话中的对齐参数是取每个变量...
  • 来源:网络,排版整理:晓宇微信公众号:芯片之家(ID:chiphome-dy)结构体的定义结构体(struct)是由系列具有相同类型或不同类型的数据构成的数据集合,也叫结构。结构体和其他类型基础数据类型一样,例如int类型,...
  • 结构体在C语言中虽然经常使用,但是怎么计算一个结构体占用多大的内存,很多C语言的新手都没注意过,其实C语言的语法简单,难就难在它更偏向于与底层,与内存打交道。对于嵌入式方面来说,对C语言的要求更高,因为...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 55,357
精华内容 22,142
关键字:

一个结构体变量所占用的空间是