结构体和共用体
1.结构体(structure):
聚合数据类型,提供一种把相关数据组合到一起的手段 1)通常,结构体的成员都是逻辑的。
2)在商业软件中,成员变量名一般习惯以下划线(_)开头。结构变量在被定义后,编译器在编译时为所有成员分配内存
3)结构体赋值:可以把一个结构变量的全局内容赋值给另一个同类的结构变量,而不必逐个成员赋值。
注意与数组的区别:数组是不能彼此赋值的,是因为数组名是一个常量指针。数组是一个数组类型的聚集,它本质上不是一个数据类型。
例子一:
jellonwu
@jintao :~/Desktop$ vim test16.c
/*计算天数*/
#include
struct DAY //DAY就是一种类型,不是变量,用的时候struct DAY date;
{
int year;
int month;
int day;
} date;/*定义一个结构并声明对象为date,date是一个变量*/
void main()
{
int days;
printf("请输入(年 月 日):");
scanf("%d %d %d",&date.year,&date.month,&date.day);
switch(date.month)
{
case 1: days = date.day;
break;
case 2: days = date.day + 31;
break;
case 3: days = date.day + 59;
break;
case 4: days = date.day + 90;
break;
case 5: days = date.day + 120;
break;
case 6: days = date.day + 151;
case 7: days = date.day + 181;
break;
case 8: days = date.day + 212;
break;
case 9: days = date.day + 243;
break;
case 10: days = date.day + 273;
break;
case 11: days = date.day + 304;
break;
case 12: days = date.day + 334;
break;
}
if(date.year%4 == 0&&date.year%100!=0||date.year%400==0)
{
if(date.month>=3)
{
days = days + 1;
}
}
printf("%d月%d是%d年的第%d天",date.month,date.day,date.year,days);
}
jellonwu
@jintao :~/Desktop$ gcc test16.c -o test16
jellonwu
@jintao :~/Desktop$ ./test16
请输入(年 月 日):2012 12 15
12月15是2012年的第350
4)向函数体传递结构时,实际上是传递结构成员的值,即都是值传递方式,包括用结构体变量作函数参数及函数返回一结构体变量两种情况
注意:与数组的区别:结构体变量名仅代表值,而非地址
除了简单结构外,向函数传递全部结构的方法存在重大缺陷:当执行函数调用时,数据压桟须需要开销。这对于多数成员结构或成员中有数组的结构,运行性能严重恶化。解决方案是:向结构传递指针
向函数传递结构指针时,压桟仅仅是指针本身,这使得函数调用非常快。在某些情况下的另一个优点是,函数可以修改作为变量的结构的内容
5)成员结构:结构体中的结构体
例子一:
jellonwu
@jintao :~/Desktop$ vim test17.c
#include
#include
struct student
{
int num;
char name[30];
char sex[10];
float score;
};
void main()
{
struct student stu;
struct student *p;
p = &stu;
stu.num = 97032;
strcpy(stu.name,"tom");
strcpy(stu.sex,"male");
stu.score = 98.5;
printf("student:%d\n姓名:%s\n性别:%s\n分数:%4.2f\n",stu.num,stu.name,stu.sex,stu.score);
printf("student:%d\n姓名:%s\n性别:%s\n分数:%4.2f\n",(*p).num,(*p).name,(*p).sex,(*p).score);
printf("student:%d\n姓名:%s\n性别:%s\n分数:%4.2f\n",p->num,p->name,p->sex,p->score);
}
jellonwu
@jintao :~/Desktop$ gcc test17.c -o test17
jellonwu
@jintao :~/Desktop$ ./test17
student:97032
姓名:tom
性别:male
分数:98.50
student:97032
姓名:tom
性别:male
分数:98.50
student:97032
姓名:tom
性别:male
分数:98.50
例子二:
jellonwu
@jintao :~/Desktop$ vim test18.c
#include
struct student
{
int num;
char name[20];
char sex;
int age;
};
struct student stu[4] = {{90,"tom",'M',10},{95,"jam",'F',15},{100,"lily",'M',17},{97,"lucy",'F',16}};
void main()
{
struct student *p;
printf("学号 姓名 性别 年龄 \n");
for(p = stu;p
{
printf("%-8d%-12s%-10c%-3d\n",p->num,p->name,p->sex,p->age);
}
}
jellonwu
@jintao :~/Desktop$ gcc test18.c -o test18
jellonwu
@jintao :~/Desktop$ ./test18
学号 姓名 性别 年龄
90 tom M 10
95 jam F 15
100 lily M 17
97 lucy F 16
6)结构体应用:结构体经常被应用于动态数据结构。在C语言中由结构体类型和动态存储分配函数来实现动态数据结构。
由于数组这样到静态数据结构在被定义后,系统将在内存中为其分配连续到内存空间,且在程序运行期间保持不变(或整体被撤销),因此虽然它有可以随机访问每一个数组元素的优点,但是它有更严重的缺陷:在对元素进行插入和删除运算时,需要移动大量元素而可能降低效率。并且,由于数组大小固定,存储在连续到内存空间中,在数据量变化较大的情况下,必须按最大需要进行分配,有可能浪费很多内存。另外,在程序运行期间无法根据需要对数组进行扩充,也不可能释放其中的某一部分内存。
在实际工作中,有很多问题需要用到动态方式到数据结构,他们占用的空间可以动态变化(可以根据需要随机地分配和释放内存)。在逻辑上连续的元素,在内存中却不一定连续。
具体实例:单向链表,二叉树
链表的例子:
jellonwu
@jintao :~/Desktop$ vim test19.c
#include
#include
struct chain
{
int value;//数据域
struct chain *next;//指针域
};
struct chain *create()
{
struct chain *head,*tail,*p;
int x;
head = tail = NULL;
printf("input data\n");
while(scanf("%d",&x)==1)//如果输入整数,向下执行
{
p = (struct chain *)malloc(sizeof(struct chain));
/*首先要为新创建到表元P开辟一个内存空间*/
p->value = x;
p->next = NULL;
if(head == NULL)
head = tail = p;
else
tail = tail->next;
tail->next = p;
}
return head;
}
void main()
{
struct chain *p,*q;
q = create();
while(q)
{
printf("%d\n",q->value);
p = q->next;
free(q);
q = p;
}
}
jellonwu
@jintao :~/Desktop$ gcc test19.c -o test19
jellonwu
@jintao :~/Desktop$ ./test19
input data
99
76
10
45
83
notnumber
99
76
10
45
83
共用体: 允许多个不同到变量(可以是相同类型或不同类型)共用统一块内存空间,提供了多种方式解释同一位模式到方法
1)声明共用体时,编译器为其分配一块内存,大小为其成员变量中最大到变量所占用到字节数。
2)共用体常用与需要频繁进行类型转换到场合,因为程序可以使用共用体中到数据
#include
union data
{
int a;
float b;
double c;
char d;
} exa;
void main()
{
exa.a = 6;
printf("%d\n",exa.a);
exa.c = 67.1;
printf("%5.1f\n",exa.c);
exa.d = 'W',
exa.b = 32.5;
int n = sizeof(exa);
printf("%5.1f\n,%c\n,%d\n",exa.b,exa.d,n);
}