结构体和联合体

3/8/2017来源:ASP.NET技巧人气:494

1.访问结构体成员,声明和初始化结构体

一个结构体是一种能同时处理多种数据类型数据的数据类型。 何时为结构体分配内存?

声明结构体类型时,并不会为结构体分配内存,只有单声明结构体变量时,才会为结构体声明类型。

下面通过实例来理解如何创建一个结构体,如何声明结构体变量,以及如何向结构体变量中读写数据。 eg1:编写一个C程序,创建一个包含多种类型成员的ebill结构体。

/*使用结构体显示电子账单*/ #include<stdio.h> #include<string.h> void main() { struct ebill { int mno; char name[20]; int PRevious; int present; int units; float charge; }; struct ebill eb; eb.mno=1005; strcpy(eb.name,"Raj Kumar"); eb.previous=500; eb.present=750; eb.units=eb.present-eb.previous; eb.charge=eb.units*4.50; printf("\nMeter no:%d",eb.mno); printf("\n------name:%s",eb.name); printf("\n-----previous:%d",eb.previous); printf("\n------present:%d",eb.present); printf("\n------units:%d",eb.units); printf("\n------charge:%f",eb.charge); }

结果如下:这里写图片描述

2.结构体指针

一个结构体指针是指用来引用结构体实例的指针。可以像声明结构体变量一样声明结构体: struct ebill *ptr; 一旦结构体指针被声明,可以使用结构体指针成员操作符或箭头操作符来引用结构体实例的数据成员。如: ptr->mno.

3.结构体数组

声明一个结构体数组:struct ebill eb[50],访问结构体的成员变量:eb[i].mno;eb[i].name;等。

fprintf()函数: 1.在显示器上显示输出。 fprintf(stdout,”Andhra Pradesh”);stdout代表标准输出设备,例如显示器。 显示一个宽度为20个字符的字符串代码如下: fprintf(stdout,”%20s”,name); 2.fprintf()函数可以将输出重定向至打印机。 fprintf(stdprn,”Hyderabad”); stdprn代表连接至计算机的标准打印机,其后紧跟着的字符串将会被发送至打印机,最后打印到纸上。 3.fprintf()也可以将输出重定向到一个文件,这样输出就可以在后续的某个时刻被再次使用。 fprintf(fptr,”%20s”,empname);

4.结构体指针数组

struct ebill *p[50];这里一共50个指针,如果想动态为结构体实例分配内存,可以使用malloc函数,如下: p[i]=(struct ebill *)malloc(sizeof(struct ebill))

5.向函数传递结构体参数

可以将整个结构体作为参数传递给函数。 eg: struct student { int rno; char name[20]; } 向display( )方法传递student结构体,函数声明如下: void display(struct student st) 这里的st是结构体变量。在函数体内,可以使用st来访问这个结构体成员,如:st.rno或st.name. 另外一种向函数传递结构体类型参数的方法是传递结构体指针。eg: void display(struct student *ptr),现在,在函数体内可以这样引用结构体成员:ptr->rno和ptr->name。 eg:结构体传参

#include<stdio.h> #include<string.h> struct student { int rno; char name[20]; }; void display(struct student st); void main() { struct student s; s.rno=10; strcpy(s.name,"Priya"); display(s); } void display(struct student st) { printf("\nrno=%d",st.rno); printf("\nName=%s",st.name); } 输出: rno=10 Name=Priya

上面的实例也可以使用结构体指针传递结构体实例。 也可以从一个函数返回一个结构体。 为了实现该目的,可以从函数中返回一个结构体指针:struct student * display (struct student *ptr) eg:向函数传递结构体指针参数,并从函数返回一个结构体指针。

#include<stdio.h> #include<string.h> struct student { int rno; char name[20]; }; struct student s={10,"Priya"}; struct student *p1,*p2; struct student *display(struct student *ptr); void main() { p1=&s; p2=display(p1); printf("\nrno=%d",p2->rno); printf("\nName=%s",p2->name); } struct student *display(struct student *ptr) { ptr->rno++; strcpy(ptr->name,"Lakshmi"); return ptr; }

6.拷贝结构体变量 可以将一个结构体实例中的数据拷贝到另外一个结构体实例中,只要两者类型相同。

struct employee { int id; char name; } struct employee e1,e2;

这里e1,e2是结构体变量。我们想将e1的内容拷贝到e2中。有两种方式可以实现该目的: 1.将e1的数据成员逐个拷贝到e2中: e2.id=e1.id; strcpy(e2.name,e1.name); 2.将一个结构体变量赋值给另一个结构体变量。使用方式如下: e2=e1. 将整个结构体的实例赋值给另一个结构体的实例是可行的,但是对于数组不可以这样操作。如果想要将一个数组中的元素拷贝到另外一个数组中,需要逐个处理数组中的元素。

#include<stdio.h> #include<string.h> struct student { int rno; char name[20]; }; struct student s={10,"Priya"}; void main() { struct student s={10,"Priya"}; struct student y; y=s; printf("\nId=%d",y.rno); printf("\nName=%s",y.name); }

结构体和数组的区别: 1)数组只能存储同一类型的数据。结构体可以存储不同类型的数据。 2)如果想将一个数组的元素拷贝至另外一个数组,则需要逐个元素拷贝。而将一个结构体实例的数据拷贝至另外一个结构体实例,只需要逐个拷贝或者直接将结构体变量赋值给另外一个结构体变量。

7.嵌套结构体 可以在一个结构体里面包含另外一个结构体。

1)雇员的id和名字。 struct employee {int id; char name[20]; } 2)雇员生日的年月日。 struct dob { int dd; int mm; int yy; }

code如下:

struct employee { int id; char name[20]; struct dob d; }; struct employee e;

结构体变量既可以当作左值也可以当作右值来处理。

编写一个结构体函数用来查找系统日期和时间。

#include<stdio.h> #include<dos.h> void main() { struct data d; struct time t; getdata(&d); gettime(&t); printf("\n%2d/%2d/%2d",d.da_day,d.da_mon,d.da_year); printf("\n%2d:%2d:%2d",t.ti_hour,t.ti_min,t.ti_sec); }

10.联合体

联合体与结构体比较类似,用关键字union来声明。 一个联合体可以有任意多个数据成员,但是只为一个联合体实例分配与最大数据成员所占内存大小相等的内存块,其他较小的数据成员也存放在该内存块中。从联合体的内存布局来看,它比结构体更节省内存,因为所有的数据成员都存放在同一块内存中。这样做的后果是,每次只能向联合体实例中存储一个数据成员,并且会覆盖之前放在该内存块的其他数据成员。