在 C 语言中我们经常会使用到 struct和 union,那么它们两个各自有何特点呢?今天我们就一探究竟。
我们先来介绍下 struct。它可以看做是变量的集合,那么一个空的结构体占多大内存呢?这是一个有趣的问题,按照理论分析,它应该是0。但是按照 C 语言的设计思想来说,不可能存在空结构体的,定义一个空结构体没意义啊,所以应该报错的。下来我们就分别在 gcc 和 BCC 编译器上实验下。由于代码比较简单,就不贴代码了,我们直接来结果。图一为在 gcc 编译器下编译的,图二为在 BCC 编译器下编译的。
图一
图二
那么我们可以看到在 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。那么这个可以编译通过吗?如果可以,它的大小又会是多少呢?我们来看看结果:
我们可以看到编译器并没有报错,也就证明是可以这样定义的,并且它的大小为 4 。这说明数组 array 并没有占用内存。下来我们来介绍下柔性数组的用法,如下图所示
我们来使用下柔性数组,代码如下:#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;
}
我们来看下编译后的结果
我们已经成功实现了一个柔性数组,可以自己指定这个数组的大小了。
下来我们来介绍下 C 语言中的 union,它在语法上跟 struct 很像。但是 union 只分配最大的成员变量的空间,所有成员共享这个空间。union 的使用受系统大小端的影响,我们来看看系统的大小端内存是怎样分配的,如下图所示:
那么在小端模式下,数据存储在低位地址上。大端则相反,但是我们的程序取数据总是从低地址开始取的。在上图中的程序中,如果系统是小端,则输出为 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;
}
我们编译后结果如下:
那么我们本节学习了 struct和 union 的有关特性,通过本节学习,总结如下:1、struct中每个数据成员有独立的存储空间,可以通过最后的数组标识符产生柔性数组;2、union中所有的数据成员共享同一个存储空间,同时它的使用会受到系统大小端的影响。后面我们会继续对 C 语言的学习。
欢迎大家一起来学习C 语言,可以加我QQ:243343083。