c语言struct union,C之 struct 和 union(十)

在 C 语言中我们经常会使用到 struct和 union,那么它们两个各自有何特点呢?今天我们就一探究竟。

我们先来介绍下 struct。它可以看做是变量的集合,那么一个空的结构体占多大内存呢?这是一个有趣的问题,按照理论分析,它应该是0。但是按照 C 语言的设计思想来说,不可能存在空结构体的,定义一个空结构体没意义啊,所以应该报错的。下来我们就分别在 gcc 和 BCC 编译器上实验下。由于代码比较简单,就不贴代码了,我们直接来结果。图一为在 gcc 编译器下编译的,图二为在 BCC 编译器下编译的。

6482c1a08396675ab0a4cddba45f1551.png

图一

8aa9c4b25ef9b1bec8de4f15cc518ae1.png

图二

那么我们可以看到在 gcc 编译器中,它支持我们的第一种看法,即认为占0个字节的内存。但是在 BCC 编译器中,它认为这样是不合法的,定义空结构体根本没必要,所以直接报错了。

那么我们在 C 语言中定义一个组数时,平常情况下只能定义大小是固定的数组。有没有什么办法让我们在 C 语言中定义一个动态大小的数组呢?办法当然是有的,这时我们就要用到我们的 struct了。我们可以利用 struct来定义一个大小待定的数组,我们称之为柔性数组。 在 C 语言中结构体的最后一个元素可以是大小未知的数组,那么在结构体中的数组便是一个待使用的标识符,并不占用存储空间。不信吗?我们来做个实验,代码如下:#include 

struct TS

{

int len;

int array[];

};

int main()

{

printf("sizeof(struct TS) = %d\n", sizeof(struct TS));

return 0;

}

我们先来分析下这个代码,结构体 TS 中定义了一个 int 类型的变量 len,还有个大小未知的数组 array。那么这个可以编译通过吗?如果可以,它的大小又会是多少呢?我们来看看结果:

c9d7a55520dcf3072b2689dde1d4a4e4.png

我们可以看到编译器并没有报错,也就证明是可以这样定义的,并且它的大小为 4 。这说明数组 array 并没有占用内存。下来我们来介绍下柔性数组的用法,如下图所示

72b850d6adcdefb0f8dbe088471f9a64.png

我们来使用下柔性数组,代码如下:#include 

#include 

struct SoftArray

{

int len;

int array[];

};

struct SoftArray* create_soft_array(int size)

{

struct SoftArray* ret = NULL;

if( size > 0 )

{

ret = (struct SoftArray*)malloc(sizeof(struct SoftArray) + sizeof(int) * size);

ret->len = size;

}

return ret;

}

void delete_SoftArray(struct SoftArray* sa)

{

free(sa);

}

void func(struct SoftArray* sa)

{

int i = 0;

if( NULL != sa )

{

for(i=0; ilen; i++)

{

sa->array[i] = i + 1;

}

}

}

int main()

{

int i = 0;

struct SoftArray* sa = create_soft_array(5);

func(sa);

for(i=0; ilen; i++)

{

printf("sa[%d] = %d\n", i, sa->array[i]);

}

delete_SoftArray(sa);

return 0;

}

我们来看下编译后的结果

f15a5af67ac51c43224b8c6d61091f00.png

我们已经成功实现了一个柔性数组,可以自己指定这个数组的大小了。

下来我们来介绍下 C 语言中的 union,它在语法上跟 struct 很像。但是 union 只分配最大的成员变量的空间,所有成员共享这个空间。union 的使用受系统大小端的影响,我们来看看系统的大小端内存是怎样分配的,如下图所示:

b28b186c74802f34eb8eb8d41bc4f15e.png

那么在小端模式下,数据存储在低位地址上。大端则相反,但是我们的程序取数据总是从低地址开始取的。在上图中的程序中,如果系统是小端,则输出为 1,反之则为 0。根据 union 这个特性,我们可以写一个判断系统大小端的函数。这道题也是笔试中我们经常会见到的,代码如下:#include 

int System_mode()

{

union SM

{

int i;

char c;

};

union SM sm;

sm.i = 1;

return sm.c;

}

int main()

{

if( 1 == System_mode() )

{

printf("小端模式\n");

}

else

{

printf("大端模式\n");

}

return 0;

}

我们编译后结果如下:

712192c5aafda5331254d1a0b62ce867.png

那么我们本节学习了 struct和 union 的有关特性,通过本节学习,总结如下:1、struct中每个数据成员有独立的存储空间,可以通过最后的数组标识符产生柔性数组;2、union中所有的数据成员共享同一个存储空间,同时它的使用会受到系统大小端的影响。后面我们会继续对 C 语言的学习。

欢迎大家一起来学习C 语言,可以加我QQ:243343083。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值