C语言提供两种结合不同类型的对象来创建数据类型的机制:结构(structure),用关键字struct声明,将多个对象集合到一个单元中;联合(union),用关键字union声明,允许用几种不同的类型来引用一个对象。
(1)结构(struct)
结构就是一个或多个变量的集合,这些变量可以为不同的类型,为了处理方便而将这些变量组织在一个名字之下。关键字struct引入结构声明。结构声明由包含在花括号内的一系列声明组成。关键字struct后面的名字是可选的,称为结构标记(structure tag)。
#include <stdio.h>#include <stdlib.h>#include <string.h>// 为字段(bit-field),即字段struct bst { unsigned int isa : 1; unsigned int isb : 1; unsigned int isc : 1;} flags;// 数据对其,要求某种类型对象的地址必须是某个值K(通常是2、4、8)的倍数。typedef struct st { // 24 char cVal; short sVal; int iVal; long lVal; double dVal;} MyStruct;typedef struct st2 { // 12 short sVal; long lVal; char cVal;} MyStruct2;typedef struct st3 { // 4 short sVal; char cVal;} MyStruct3;void PRintTypeSize(){ printf("sizeof(void *): %d/n", sizeof(void *)); printf("sizeof(int): %d/n", sizeof(int)); printf("sizeof(char): %d/n", sizeof(char)); printf("sizeof(short): %d/n", sizeof(short)); printf("sizeof(long): %d/n", sizeof(long)); printf("sizeof(float): %d/n", sizeof(float)); printf("sizeof(double): %d/n", sizeof(double));}int main(){ MyStruct stVal = { 1, 2, 3.0, 'a' }; printf("sizeof(stVal): %d/n", sizeof(stVal)); // 24 printf("&stVal.cVal: 0x%x/n", &stVal.cVal); printf("&stVal.sVal: 0x%x/n", &stVal.sVal); printf("&stVal.iVal: 0x%x/n", &stVal.iVal); printf("&stVal.lVal: 0x%x/n", &stVal.lVal); printf("&stVal.dVal: 0x%x/n/n", &stVal.dVal); printf("sizeof(MyStruct2): %d/n", sizeof(MyStruct2)); // 12 printf("sizeof(MyStruct3): %d/n", sizeof(MyStruct3)); // 12 printf("sizeof(flags): 0x%x/n", sizeof(flags)); // 4 PrintTypeSize(); getchar(); return 0;}长度为0的数组
1)长度为0的数组并不占有内存空间,而指针方式需要占用内存空间。
2)对于长度为0数组,在申请内存空间时,采用一次性分配的原则进行;对于包含指针的结构体,在申请空间时需分别进行,释放时也需分别释放。
3)对于长度为的数组的访问可采用数组方式进行。
typedef struct { // 4 unsigned int length; int contents[0]; // 不占用内存} Line;int main(){ Line *pstTest = NULL; unsigned int length = 12; printf("sizeof(MyStruct): %d/n", sizeof(Line)); pstTest = (Line *)malloc(sizeof(Line) + sizeof(int) * length); pstTest->length = length; for (int i = 0; i < length; i++) { pstTest->contents[i] = i + 1; printf("pstTest->contents[%d]: %d/n", i, pstTest->contents[i]); } getchar(); return 0;}(2)联合(union)
联合是可以(在不同时刻)保存不同类型和长度的对象的变量,编译器负责跟踪对象的长度和对齐要求。联合提供了一种方式,以在单块存储区中管理不同类型的数据,而不需要在程序中嵌入任何同机器有关的信息。
实际上,联合就是一个结构,它的所有成员相对与基地址的偏移量都为0,此结构空间要大到足够容纳最“宽”的成员,并且,其对齐方式要适合与联合中所有类型的成员。
联合只能用其第一个成员类型的值进行初始化。
union U { unsigned int nVal; unsigned char cArr[4];};int main(){ union U uTest; uTest.nVal = 0x12345678; printf("union uTest/n", uTest.nVal); printf("uTest.nVal: 0x%x/n", uTest.nVal); for (int i = 0; i < 4; i++) { printf("uTest.arr[%d]: 0x%x/n", i, uTest.cArr[i]); } getchar(); return 0;}
新闻热点
疑难解答