成都网站建设设计

将想法与焦点和您一起共享

C之struct和union(十)

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

创新互联专业提供成都主机托管四川主机托管成都服务器托管四川服务器托管,支持按月付款!我们的承诺:贵族品质、平民价格,机房位于中国电信/网通/移动机房,雅安电信机房服务有保障!

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

C之 struct 和 union(十)

                                              图一

C之 struct 和 union(十)

                                                        图二

        那么我们可以看到在 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。那么这个可以编译通过吗?如果可以,它的大小又会是多少呢?我们来看看结果:

C之 struct 和 union(十)

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

C之 struct 和 union(十)

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

#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之 struct 和 union(十)

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

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

C之 struct 和 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;
}

        我们编译后结果如下:

C之 struct 和 union(十)

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

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


名称栏目:C之struct和union(十)
浏览地址:http://chengdu.cdxwcx.cn/article/jpgjjs.html