结构与联合

结构和联合

结构:

   struct SELF_REF1{

     int a;

     struct SELF_REF1 b;

     int c;

};

这是一种错误的自引用,结构内包含结构体,它也包含自己的b,这样就是一个无止尽的递归程序,相反,换成下面这样,就是正确的。

   struct SELF_REF1{

     int a;

     struct SELF_REF1 *b;

     int c;

};

因为编译器在结构的长度确定之前就已经知道指针的长度,所以这种自引用是正确的。

结构的存储分配

      struct Align{

      char a;

      int b;

      char c;

};

如果某个机器的整型值长度为4个字节,并且它的存储位置必须被4整除,那么这个结构在内存的存储将如下所示:


这种做法将导致内存浪费。

我们对其成员顺序进行一个调整,如下:

struct Align{

   int b;

   char a;

   char c;

};

这个结构跟前面的一样,但是它只占用8字节,节省33%,两个字符可以紧挨存储,所以只有结构最后面需要跳过两个字节才被浪费。

注:offsetof宏可以用来确定结构中某个成员的实际位置。

offsetof(type,member);

如:

对前面声明的结构体而言,Offsetof(struct Align,b)的返回值是4;

作为函数参数的结构优劣评估

比如有下列结构:

typedef struct{

    char product[20];

    int quality;

    float unit_price;

    float total amount;

}Transaction;

现在有个打印函数,并有以下个原型:

void print_receipt(Transaction trans)//结构传递方案

void print_receipt(Transaction* trans); //指针传递方案

这两种的差别在于,第一种传入的是结构体,因为C语言的参数传值调用方式要求把参数的一份拷贝传递给函数,这个结构体共占32个字节,采用这种方式,必须将32个字节复制到堆栈,以后再丢弃。

而第二种传入的是指针,指针比整个结构小得多,所以把它压入堆栈效率高得多,不过,对结构成员的修改将会产生影响。

在结构特别小时,结构传递方案才不会输给指针传递方案。但在绝大多数情况下,指针传递明显效率更高。

联合:

   联合的所有成员引用的是内存的统一位置,当你想在不同时刻把不同的东西存储于同一个位置时,就使用联合。

看一个简单例子:

union{

   int a;

   float b;

}fi;

  在一个浮点数和整数都是32位的机器上,变量fi只占用内存中的一个32位的字,如果成员b被使用,这个字就作为浮点数访问,与此相同,a也是一样。

使用联合体可以减少内存使用浪费。

如下:

   struct variable{

   enum {INT,FLOAT,STRING}type;

   int int_value;

   float float_value;

   char* string_value;

};

分析:该结构主要是根据type的值来输出值的不同类型表示;

但是这里低效的原因就是内存的占用问题——每个variable结构存在两个问使用的值字段。用联合体可以解决这个问题,如下:

struct variable{

   enum {INT,FLOAT,STRING}type;

    union{

       int int_value;

       float float_value;

       char* string_value;

     }

};

type只作为程序员自己负责,内存并不对其进行证实程序使用的是正确的联合成员,而联合体的内存只使用了4个字节,同一位置存储了三种不同类型的值。

联合的长度就是其最长成员的长度。

    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值