我们先来介绍下 struct 。它可以看做是变量的集合,那么一个空的结构体占多大内存呢?这是一个有趣的问题,按照理论分析,它应该是0。但是按照 C 语言的设计思想来说,不可能存在空结构体的,定义一个空结构体没意义啊,所以应该报错的。下来我们就分别在 gcc 和 BCC 编译器上实验下。由于代码比较简单,就不贴代码了,我们直接来结果。图一为在 gcc 编译器下编译的,图二为在 BCC 编译器下编译的。
图一
图二
那么我们可以看到在 gcc 编译器中,它支持我们的第一种看法,即认为占0个字节的内存。但是在 BCC 编译器中,它认为这样是不合法的,定义空结构体根本没必要,所以直接报错了。
那么我们在 C 语言中定义一个组数时,平常情况下只能定义大小是固定的数组。有没有什么办法让我们在 C 语言中定义一个动态大小的数组呢?办法当然是有的,这时我们就要用到我们的 struct 了。我们可以利用 struct 来定义一个大小待定的数组,我们称之为柔性数组。 在 C 语言中结构体的最后一个元素可以是大小未知的数组,那么在结构体中的数组便是一个待使用的标识符,并不占用存储空间。不信吗?我们来做个实验,代码如下:
#include <stdio.h> 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 <stdio.h> #include <malloc.h> 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; i<sa->len; i++) { sa->array[i] = i + 1; } } } int main() { int i = 0; struct SoftArray* sa = create_soft_array(5); func(sa); for(i=0; i<sa->len; i++) { printf("sa[%d] = %d\n", i, sa->array[i]); } delete_SoftArray(sa); return 0; }
我们来看下编译后的结果
我们已经成功实现了一个柔性数组,可以自己指定这个数组的大小了。
下来我们来介绍下 C 语言中的 union,它在语法上跟 struct 很像。但是 union 只分配最大的成员变量的空间,所有成员共享这个空间。union 的使用受系统大小端的影响,我们来看看系统的大小端内存是怎样分配的,如下图所示:
那么在小端模式下,数据存储在低位地址上。大端则相反,但是我们的程序取数据总是从低地址开始取的。在上图中的程序中,如果系统是小端,则输出为 1,反之则为 0。根据 union 这个特性,我们可以写一个判断系统大小端的函数。这道题也是笔试中我们经常会见到的,代码如下:
#include <stdio.h> 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。
原文地址:http://blog.51cto.com/12810168/2095358