结构

来源:互联网 发布:手机时间与网络同步 编辑:程序博客网 时间:2024/04/30 07:17

C语言提供两种结合不同类型的对象来创建数据类型的机制:结构(structure),用关键字struct声明,将多个对象集合到一个单元中;联合(union),用关键字union声明,允许用几种不同的类型来引用一个对象。

(1)结构(struct)

结构就是一个或多个变量的集合,这些变量可以为不同的类型,为了处理方便而将这些变量组织在一个名字之下。关键字struct引入结构声明。结构声明由包含在花括号内的一系列声明组成。关键字struct后面的名字是可选的,称为结构标记(structure tag)。

数组也可以看成是一个或多个类型相同的变量的集合)

结构的初始化,初始化式中的成员数可以少于它所初始化的结构,就像数组那样,任何“剩余的”成员都用0作为它的初始值。特别地,剩余的字符数组中的字节数为0,表示空字符串。结构的赋值操作——结构可以拷贝、赋值、传参或作为函数返回值。

结构在使用之前应进行初始化或赋值。

#include <stdio.h>#include <stdlib.h>#include <string.h>#define BUF_LEN 32struct person {char name[BUF_LEN];int age;int gender;char address[BUF_LEN];};void PrintPerson(struct person *p){printf("name: %s\n", p->name);printf("age: %d\n", p->age);printf("gender: %d\n", p->gender);printf("address: %s\n", p->address);}int main(){struct person a = { 0 };struct person b;struct person c;struct person d;printf("\nperson a\n");PrintPerson(&a);memcpy(b.name, "jinagxt", sizeof("jinagxt"));b.age = 28;b.gender = 1;memcpy(b.address, "wuhan", sizeof("wuhan"));printf("\nperson b\n");PrintPerson(&b);memset(&c, 0, sizeof(c));printf("\nperson c\n");PrintPerson(&c);printf("\nperson d\n");PrintPerson(&d);d = b; // 赋值printf("\nperson d\n");PrintPerson(&d);getchar();return 0;}

#include <stdio.h>#include <stdlib.h>#include <string.h>// 数据对其,要求某种类型对象的地址必须是某个值K(通常是2、4、8)的倍数。typedef struct st { // 24char cVal;short sVal;int iVal;long lVal;double dVal;} MyStruct;typedef struct st2 { // 12short sVal;long lVal;char cVal;} MyStruct2;typedef struct st3 { // 4short 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)); // 24printf("&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)); // 12printf("sizeof(MyStruct3): %d\n", sizeof(MyStruct3)); // 12printf("sizeof(flags):     0x%x\n", sizeof(flags));   // 4PrintTypeSize();getchar(); return 0;}

长度为0的数组

1)长度为0的数组并不占有内存空间,而指针方式需要占用内存空间。

2)对于长度为0的数组,在申请内存空间时,采用一次性分配的原则进行;对于包含指针的结构体,在申请空间时需分别进行,释放时也需分别释放。

3)对于长度为0的数组的访问可采用数组方式进行。

typedef struct {     // 4unsigned 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;}


1 0
原创粉丝点击