精华内容
下载资源
问答
  • c语言结构体union

    2017-04-08 14:15:40
    c语言结构体定义: 1.先定义结构体数据类型,再声明变量 struct s_name { 成员... }; struct s_name var_name;//声明变量,在c++里struct可以不写。 2.定义结构体类型的同时,声明变量 struct s_name { ...

    c语言结构体定义:

    1.先定义结构体数据类型,再声明变量

    struct s_name

    {

    成员...

    };

    struct s_name var_name;//声明变量,在c++里struct可以不写。

    2.定义结构体类型的同时,声明变量

     

    struct s_name

    {

    成员...

    }var_name1,var_name2;   //在此声明变量

    3.定义一个结构体,只能有有限个变量时

     

    struct {

    成员...

    }var_name1,var_name2;

    该结构体只有两个变量,由于该结构体无名,所有不能用来声明变量。

    4.使用typedef为结构体(自定义)数据类型取别名

    typedef struct s_name

    {

    成员...

    } tt; //tt表示struct s_name 这个数据类型,之后可以通过tt直接声明结构体类型如:tt var;

     

    关于结构体赋值:分为两类

    struct stu{int sno;int id;int n;};

    1.定义是初始化

    顺序初始化:

    struct stu s={3,4,5};//这种必须给结构体每个成员赋值

    乱序初始化:

    struct stu s1={.id=5,.n=9};//这种方式可以任意给指定成员赋值,这是c风格,只能在.c文件使用

    struct stu s2={id:5,n:9};//这种方式是c++风格,在.cpp文件使用

    上面必须是在定义时,赋值。

    2.先定义后赋值

    struct stu s2;

    s2.sno=0; s2.id=9;s2.n=8;//等待

    另外,相同类型的变量(对象)可以互相赋值;

    struct stu s4= s2;

    关于结构体大小的问题

     

           首先有编译器编译时有个设置,结构体对齐基数,一般为4字节或8字节。计算结构体的方法有一下三点;

          (1)结构体的第一个成员变量为结构体的首地址

          (2)之后,其余成员变量相对结构体的首地址的偏移量为对齐基数和该成员变量字节大小较小值的整数倍

         (3)最后,总结构体大小要为结构体里成员变量基本类型最大的字节数和对齐基数较小值的整数倍

     

    通过宏#pragma pack(x)来修改对齐基数,默认对齐基数一般为4.如下面例子:

    #pragma pack(2)

    struct dd{ char a[13]; int b; };

    此时sizeof(dd)结果为:18;

    #pragma pack(4)

    struct dd{ char a[13]; int b; };

    此时sizeof(dd)结果为:20;

    附加:

           c++ string类型字节数为:28

     

    union 联合体与结构体类似,区别为:联合体多个成员使用一块内存。 也就是同一时刻只存在一个有效成员。定义,赋值均和结构体一样。union联合体没有this指针。

    union联合体大小为最大成员所占内存。

    union之间不能直接使用==判断是否相等;需要重载==运算符

    struct之间不能直接使用==判断两个结构体是否相等,需重载==运算符。

     

    总结:对于基本类型(int,double,char,char*,float),编译器有自己的比较方式,即上述两个相同的基本数据类型可以直接使用关系运算符比较。

              复杂类型(union,struct(和class一样)),编译器不知道怎么比较,因此,上述两个相同的数据类型不能直接使用关系运算符来比较,需要重载关系运算符,来告诉编译器比较方式。

    展开全文
  • 结构体union

    2013-07-11 23:08:52
    struct和union结构体和联合体的区别(转) 共用体  构造数据类型,也叫联合体  用途:使几个不同类型的变量共占一段内存(相互覆盖)  结构体是一种构造数据类型  用途:把不同类型的数据组合成一个整体----...

    structunion结构体和联合体的区别()

    共用体 
    构造数据类型,也叫联合体 
    用途:使几个不同类型的变量共占一段内存(相互覆盖) 

    结构体是一种构造数据类型 
    用途:把不同类型的数据组合成一个整体-------自定义数据类型 

    --------------------------------------------------------------- 


    结构体变量所占内存长度是各成员占的内存长度的总和。 


    共同体变量所占内存长度是各最长的成员占的内存长度。 


    共同体每次只能存放哪个的一种!! 

    共同体变量中起作用的成员是尊后一次存放的成员, 
    在存入新的成员后原有的成员失去了作用! 

    --------------------------------------------------------------- 


    Structure 与 Union主要有以下区别: 

    1. structunion都是由多个不同的数据类型成员组成但在任何同一时刻, union中只存放了一个被选中的成员struct的所有成员都存在。在struct中,各成员都占有自己的内存空间,它们是同时存在的。一个struct变量的总长度等于所有成员长度之 和。在Union中,所有成员不能同时占用它的内存空间,它们不能同时存在。Union变量的长度等于最长的成员的长度。 

    2. 对于union的不同成员赋值将会对其它成员重写原来成员的值就不存在了而对于struct的不同成员赋值是互不影响的。 



    举一个例子: 

    例:

    #include <stdio.h> 

    void main() 
    {       
    union{                                                /*定义一个联合*/       
    int i;       
    struct{                                     /*在联合中定义一个结构*/       
    char first;       
    char second;       
    }half;       
    }number;       
    number.i=0x4241; /*联合成员赋值*/       
    printf("%c%c\n", number.half.first, number.half.second);       
    number.half.first='a';                  /*联合中结构成员赋值*/       
    number.half.second='b';       
    printf("%x\n", number.i);

                             system("pause"); 
    } 

    输出结果为: 
    AB 
    6261

    分析:

    union的成员是共用内存的
    union{ 
    int i; 
    struct{ 
    char first; 
    char second;
    }half;
    }number; 
    number.i=0x4241;

    在这里和 half结构是共用内存

    number.i=0x4241i赋值后,内存中以二进制存储0100 0010 0100 0001
    按顺序对应到结构中
    halt.first=01000010   转换成10进制就是66(字母Aasc码)
    halt.second=01000001 转换成10进制是65   (字母Basc码)
    所以输出后就是 AB

    下面同理了

    ==========================================================================

    第一题: 
    include <stdio.h> 
    union 
    { 
    int i; 
    char x[2]; 
    }a; 
    void main() 
    { 
    a.x[0] = 10; 
    a.x[1] = 1; 
    printf("%d",a.i); 
    } 
    答案:266 
    第二题: 
    main() 
    { 
    union{ /*定义一个联合*/ 
    int i; 
    struct{ /*在联合中定义一个结构*/ 
    char first; 
    char second; 
    }half; 
    }number; 
    number.i=0x4241; /*联合成员赋值*/ 
    printf("%c%c\n", number.half.first, mumber.half.second); 
    number.half.first='a'; /*联合中结构成员赋值*/ 
    number.half.second='b'; 
    printf("%x\n", number.i); 
    getch(); 
    } 
    答案: AB 6261

    C语言中的联合体(UNION)的概念是,联合体中的多种数据类型共享同一个内存空间。就拿你举的例子来说: 
    union 
    { 
    int i; 
    char x[2]; 
    }a; 
    在联合体a中定义了两种数据类型,字符数组x以及整形变量i.其中整形变量是16位的,数组大小为2的字符数组为8X216位。如此一来,编译器便会为 联合体a在内存中开辟一个16位的空间,这个空间里存储联合体的数据,但是这个空间只有16位,它既是整形变量的数据,也是字符数组的数据。如果你的程序 从字符数组的角度解析这个空间,那么它就是两个字符,如果你的程序从整型的角度解析这个空间,那么它就是一个整数。 
    以你的程序为例子,现在已经开辟了一个16位的空间,然后我们假定现在空间还没有被赋值,为: 
    00000000 00000000 
    那么在运行完代码 
    a.x[0] = 10; 
    a.x[1] = 1; 
    之后,16位的空间变为: 
    00000110 00000001 
    然后程序运行 
    printf("%d",a.i); 
    就是把联合体a当成一个整数来解析,而不是字符串数组。那么这样一来,程序就把这16位变成了一个完整的整数: 
    (00000001 00000110)二进制 = (266)十进制 
    注意,你可以看到程序在把16位弄成整数的时候把后面八位放在了前面,前面八位放在了后面。这个反序是计算机存储结构造成的,这个和联合体没有直接关系。如果感兴趣的话可以参考汇编语言。 
    就是这个道理。

    第二个例子同样, 
    union{ /*定义一个联合*/ 
    int i; 
    struct{ /*在联合中定义一个结构*/ 
    char first; 
    char second; 
    }half; 
    }number; 

    定义了联合体number,这个联合体有两种数据类型,整形i(16位),以及一个结构体(struct half)(2char16位)。所以编译器为这个联合体开辟一个16位的空间: 
    00000000 00000000 
    然后赋值: 
    number.i=0x4241; 
    这个时候,联合体以整形的身份出现,16位的空间将被整体认为是一个整数赋值。 
    注意(0x4241)(16进制) = (01000010 01000001)二进制。还记得刚才说的,计算机存储的时候是反着存的吗,先存低位,再存高位(参考汇编语言),因此16位地址被赋值位 
    01000001 01000010 
    然后 
    printf("%c%c\n", number.half.first, mumber.half.second); 
    实际上是把16位空间以结构体half的角度解析,也就是两个char. 
    那么第一个:number.half.first = (01000001)二进制 = (65)十进制 = A(ASCII码) 
    同理number.half.second = B(ASCII码) 
    当然后头又给firstsecond赋值位"a""b",这样会把16位空间弄成是: 
    01100001 01100010 
    然后用 
    printf("%x\n", number.i); 
    就是把16位看成整数,记住高地位反过来 
    01100010 01100001)二进制 =   (0X6261)16进制 
    所以结果就是:0x6261. 

    getch(); 
    最后记得按任意键结束程序。

    展开全文
  • 结构体: ​ 结构是由程序员自己设计的一种数据类型,用于描述一个事物的各项数据,由若干个不同的基础类型组成。 设计: struct 结构体名 { 类型1 成员名1; 类型2 成员名2; ... }; 定义结构变量: struct ...

    复合结构类型

    结构体:

    ​ 结构是由程序员自己设计的一种数据类型,用于描述一个事物的各项数据,由若干个不同的基础类型组成。

    设计:
    struct 结构体名
    {
        类型1	成员名1;
        类型2	成员名2;
        ...
    };
    定义结构变量:
        struct 结构体名	结构变量名;
    		注意:定义结构体变量时,struct不能省略
    定义结构变量初始化:
        struct 结构名 结构变量名 = {v1,v2,v3};
    		注意:要根据结构体设计的顺序初始化
    	struct 结构名 结构变量名 = {.成员名2=v2,.成员名3=v3};
    		只初始化某些成员
            注意:同类型的结构变量可以直接赋值,变量名1=变量名2;
    访问结构成员:结构体名.成员名
    

    结构变量做形参时:

    ​ 由于结构变量的字节数比较大,值传递的效率比较低,因此都是传递结构体的地址,当使用的是结构体指针时,那么使用->来访问成员。如果不需要修改结构变量的值,可以使用const来保护。

    ​ 结构体->成员名;

    typedef重定义结构类型:

    ​ typedef struct 结构类型名 结构类型名;

    ​ 之后就可以不用sturct关键字了

    ​ typedef struct 结构类型名

    ​ {

    ​ 类型 成员名;

    ​ …;

    ​ }结构类型名;

    注意:一般使用堆内存存放结构体变量。

    计算结构体字节数

    ​ 结构体的成员的顺序会影响它的总字节数,如果在设计结构体时能够合理地安排成员的顺序可以大大节省内存。

    ​ 内存对齐:

    ​ 假定第一个成员从零地址开始算,储存每个成员地址编号必须能被它的类型的字节数整除

    ​ 内存补齐:

    ​ 结构体的总字节数,必须是它最大成员的字节数的整数倍,如果不是整数倍,则在末尾填充空字节。

    ​ 在Linux系统下计算结构体的对齐和补齐时,如果成员的字节数大于4个字节,则以4个字节计算。Windows下是按实际情况计算的

    ​ #pragma pack(n) 设置对齐、补齐的最大字节数 n<=4

    联合:union

    ​ 联合与结构的使用方法基本一致,与结构的区别就是所有的成员共用一块内存,一个成员的值发生变化,其他所有成员的值也会随之改变。

    ​ 联合就是使用少量的内存对应多个标志符,来达到节约内存的目的,现在已经基本不使用了。

    ​ 联合常考的笔试题:

    union Date
    {
        char ch[10];
        int num;
    };
    

    ​ 注意:计算联合体时要考虑内存补齐

    如何判断系统是大端还是小端?

    ​ 如果十六进制整数0x01020304 储存在以0x0A为起始地址的4字节内存中

    ​ 高位数据存在高位地址——小端 (0A:04 0B:03 0C:02 0D:01)

    ​ 高位数据存在低位地址——大端 (0A:01 0B:02 0C:03 0D:04)

    #include<stdio.h>
    
    union Date
    {
        char ch[10];
        int num;
    };
    
    int main(int argc,const char* argv[])
    {
        union Date date;
        date.num = 0x01020314;
        printf("%hhd\n",date.ch[0]);
        //union Date d = {};
        //d.num = 123;
        //printf("%hhd %d",d.ch,d.num);
    }
    

    ​ 个人计算机系统一般都是小端系统,而UNIX服务器和网络设备都是大端系统,网络字节序也是大端模式的数据

    ​ 序列化和反序列化(sprintf,xml,json)

    枚举:enum

    ​ 枚举就是一种数据类型把可能出现的值全部罗列出来,取一个有意义的名字,除此之外,该类型的变量再出现别的数值就是非法的(愿望)。

    ​ 枚举就可以看作是数值受限的int类型,但编译器为了效率,并不会检查,所有的C语言中的枚举都可以当做正常的int类型。

    #include<stdio.h>
    
    enum Direction {UP=183,DOWN=184,RIGHT=185,LEFT=186};
    
    int main(int argc,const char* argv[])
    {
        enum Direction k = UP; 
        printf("%d",k);
    }
    

    如果不给成员值,枚举的值默认从0开始,逐渐+1,如果设置了值,后面没设置的会在它的基础上+1。

    ​ 为什么要使用枚举:

    ​ 为没有意义的值取一个有意义的名字,提高代码的可读性。

    展开全文
  • 请牢记以下3条原则:(在没有#pragma pack宏的情况下) 1:数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个...2:结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素

    请牢记以下3条原则:(在没有#pragma pack宏的情况下)

    1:数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储。

    2:结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.)

    3:收尾工作:结构体的总大小,也就是sizeof的结果,.必须是其内部最大成员的整数倍.不足的要补齐.

    等你看完此3条原则,2分钟已经过去,抓紧时间,实战3分钟:

    typedef struct bb
    {
     int id;             //[0]....[3]
     double weight;      //[8].....[15]      原则1
     float height;      //[16]..[19],总长要为8的整数倍,补齐[20]...[23]     原则3
    }BB;

    typedef struct aa
    {
     char name[2];     //[0],[1]
     int  id;         //[4]...[7]          原则1

     double score;     //[8]....[15]    
     short grade;    //[16],[17]        
     BB b;             //[24]......[47]          原则2
    }AA;

    int main()
    {
      AA a;
      cout<<sizeof(a)<<" "<<sizeof(BB)<<endl;
      return 0;
    }

    结果是

    48 24
    ok,上面的全看明白了,内存对齐基本过关.

    再讲讲#pragma pack().

    在代码前加一句#pragma pack(1),你会很高兴的发现,上面的代码输出为

    32 16
    bb是4+8+4=16,aa是2+4+8+2+16=32;

    这不是理想中的没有内存对齐的世界吗.没错,#pragma pack(1),告诉编译器,所有的对齐都按照1的整数倍对齐,换句话说就是没有对齐规则.

    明白了不?

    那#pragma pack(2)的结果又是多少呢?对不起,5分钟到了,自己去测试吧.

    ===============================================================

    一会搞定union内存字节对齐
    也是转载一个论坛的回复:

    其实union(共用体)的各个成员是以同一个地址开始存放的,每一个时刻只可以存储一个成员,这样就要求它在分配内存单元时候要满足两点:   
      1.一般而言,共用体类型实际占用存储空间为其最长的成员所占的存储空间;   
      2.若是该最长的存储空间对其他成员的元类型(如果是数组,取其类型的数据长度,例int   a[5]为4)不满足整除关系,该最大空间自动延伸;   
        
      我们来看看这段代码:   
      union   mm{   
      char   a;//元长度1   
      int   b[5];//元长度4   
      double   c;//元长度8   
      int   d[3];   
      };   
      本来mm的空间应该是sizeof(int)*5=20;但是如果只是20个单元的话,那可以存几个double型(8位)呢?两个半?当然不可以,所以mm的空间延伸为既要大于20,又要满足其他成员所需空间的整数倍,即24   
        
      所以union的存储空间先看它的成员中哪个占的空间最大,拿他与其他成员的元长度比较,如果可以整除,ok

     

    展开全文
  • #include &lt;stdio.h&gt; #include &...union U1 { char s[9]; //偏移为0 int n; //偏移为0 double d; //偏移为0 }; union U2 { char s[5]; int n; double d; }; int main(i...
  • 5分钟搞定内存字节对齐 ... 请牢记以下3条原则:(在没有#...1:数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整
  • union { /* printer only fields */ struct { short dmOrientation; short dmPaperSize; short dmPaperLength; short dmPaperWidth; short dmScale; short dmCopies; short dmDefaultSource; ...
  • 这句话的对齐参数有点复杂它是取结构体中: min (所有变量的对齐参数的最大值, 系统默认对齐参数 #pragma pack(n))。 举个例子: ① #pragma pack(2) struct {int a, short b} , 整体便是 min (max(a,b) , 2...
  • [color=#FF0000]但是把结构体改成union就没法用,高手指教。[/color] typedef union _reg1 { unsigned char BYTE; struct _Bit{ unsigned char reg1_0 :1; unsigned char reg1_1 :1; unsigned char reg1...
  • 转载学习结构体union大小的问题

    千次阅读 2009-08-24 19:00:00
    5分钟搞定内存字节对齐转载:http://blog.csdn.net/hairetz/archive/2009/04/16/4084088.aspx请牢记以下3条原则:(在没有#pragma pack宏的情况下)1:数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一...
  • 当我们编写完一个模块,我们需要提供的是H的文件给其他模块使用,我们希望H文件就只能包含一些公有函数,和一些类型的申明,不希望其他模块篡改我们C文件私有的变量,访问我们的私有方法,strongswan的代码实现...
  • 结构体 union

    2011-06-08 20:55:27
    结构体类型名称是struct 结构体名,注意struct关键字不能省略 struct student stu[10], p=stu; ++p->num; /* 同++(p->num); */ p++->num; /* 同(p++)->num; */ 变量的定义 定义共用体类型的同时定义变量。 先定义...
  • 设计程序时,最重要的步骤之一是选择表示数据的方法。 在许多情况下,简单变量甚至是数组还不够。为此,C提供了结构体变量提高表示数据的能力,它能让你创造新的...在结构体声明,用一对花括号括起来的是结构成...
  • typedef struct _zval_struct { zvalue_value value; zend_uint refcount; zend_uchar type; zend_uchar is_ref; } zval;
  • 首先一句话——在C++结构体和类没有什么区别,唯一的区别就是:默认的访问权限和继承访问权限不同。其他的,类能怎么干,结构体也能怎么干! 默认访问权限:结构体是public,类是private 默认继承访问权限:...
  • 通过将结构体和一个数组来遍历结构体成员,这种方法有一个弊端是要求结构体成员的类型要一样,但是对于数据校验来说,这也是一种方法。 转载于:https://www.cnblogs.com/CoderTian/p/5019082.html
  • 在C语言,还有另外一种和结构体非常类似的语法,叫做共用体(Union),它的定义格式为: union 共用体名{ 成员列表 }; 共用体有时也被称为联合或者联合体,这也是 Union 这个单词的本意。 结构体和共用体的...
  • 结构体struct 联合体union 及内存对齐

    千次阅读 2015-09-24 10:33:43
    当在C定义了一个结构类型时,它的大小是否等于各字段...ANSI C对结构体的内存布局有什么要求?而我们的程序又能否依赖这种布局?这些问题或许对不少朋友来说还有点模糊,那么本文就试着探究它们背后的秘密

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 44,957
精华内容 17,982
关键字:

结构体中union