结构体是一种构造数据类型,可将不同类型的数据构成一个集合,用于描述复杂的对象。通过使用结构体数组可以实现大规模对象的存储于处理。
一:结构体类型的声明
一般格式为
struct 结构体类型名 //声明结构体
{
数据类型 属性1;
...
数据类型 属性n;
}
例如:
struct information
{
char name[9];
int age;
char tel;
};
结构体类型的定义可以嵌套,即可以利用一个已定义的结构体类型作为另一个结构体类型的属性
例如:
struct date
{
int year;
int month;
int day;
};
struct information
{
char name[9];
struct date birthday;//将age属性修改成birthday属性
char tel;
};
二、结构体变量的定义与操作
1、结构体变量的定义
结构体类型与结构体变量的区别:
结构体类型仅是一个框架,系统不会给结构体类型分配空间,仅对结构体变量分配空间
一般格式为:
struct 结构体名 结构体变量名;
例如:
struct information i1;
//为了方便书写,可以用类型定义符typedef将struct student命名成为一个新名称
//infor等价于information
typedef struct information infor;
//再用infor定义结构体变量i1、i2
infor i1,i2;
1)、结构体变量的定义可以放在结构体的声明之后:
struct information
{
char name[9];
int age;
char tel;
};
struct information i1;
2)、结构体变量的定义也可以与结构体的声明同时,这样就简化了代码:
struct information
{
char name[9];
int age;
char tel;
}i1;
3)、还可以使用匿名结构体来定义结构体变量
struct //没有结构体类型名
{
char name[9];
int age;
char tel;
}i1;
2、结构体变量的操作
由于结构体变量的成员一般分属不同的数据类型,故不能直接对整个结构体变量进行输入输出等操作,对结构体变量的操作应以其属性为基本单位
一般格式为:
结构体变量名.成员名 //“.”为成员运算符
例如:
i1.name //表示i1的名字
使用时遵守以下原则
1)、在访问结构体变量的成员时,要根据结构体变量的成员类型来进行相应的操作
例如:
strcpy(i1.name,"zhangsan"); //将zhangsan存入i1的name里
2)、对于嵌套的结构体变量,应该逐级访问其成员,直至非结构成员
例如:
i1.birthday.year = 2000;
3)、两个同类型的结构体变量可以直接赋值,赋值号右边结构体变量的成员依次赋值给左边结构体变量的各个成员
例如:
i1 = i2;
3、结构体变量的初始化
数据顺序应该与结构体中的成员顺序及类型一致,且当成员不能初始化时,不能留空,应该使用默认值进行初始化,以免发生错位。
例如:
infor i1 = {"zhangsan",2000,0,0,""}
三、指向结构体的指针
结构体可以通过定义指针变量来保存结构体变量的首地址。
一般格式为:
结构体类型名 *指针变量名
例如:
infor i1,*p;
p = &i1; //p保存s的首地址
当结构体指针指向某结构体变量后,借助指针可以访问该指针指向的对象属性
1)、通过“(*指针).属性名”来访问指针指向的对象的属性
例如:
scanf("%d",(&p).birthday.year);
2)、通过“指针->属性名”来访问指针指向的对象属性
当p指向结构体变量i1的指针时,借助p来应引用i1的的各个成员
例如:
p->birthday.year可引用i1的出生年份
当p为结构体类型的指针时,可以通过malloc函数来为p动态分配结构体空间,并且当p指向的动态结构体使用完后,应采用free§;语句将空间释放
例如:
infor *p;
p = (infor *)malloc(sizeof(infor));
四、向函数传递结构体
结构体变量可以作为函数参数传递给函数使用
1)、值传递
传值调用可为单向值传递,函数调用发生时,系统将结构体变量的值复制一份给形参,在函数中所有的操作都是针对形参进行的,实参的值不会因形参的值改变而改变
例如:
#include<stdio.h>
struct date
{
int year;
int month;
int day;
};
typedef struct date d;
void fun(d d)
{
d.year = 0000;
d.month = 00;
d.day = 00;
}
int main()
{
d d = {2000,0,0};
printf("%d,%d,%d\n",d.year,d.month,d.day);
fun(d);
printf("%d,%d,%d\n",d.year,d.month,d.day);
return 0;
}
结果为:
2)、地址传递
当函数的形参作为指向结构体的指针类型时,可以将结构体变量的地址作为函数的实参,完成结构体变量的传地址调用
例如:
#include<stdio.h>
struct date
{
int year;
int month;
int day;
};
void fun(struct date *p)
{
p->year = 20000;
p->month = 00;
p->day = 00;
}
int main()
{
struct date d= {2000,1,1};
printf("%d,%d,%d\n",d.year,d.month,d.day);
fun(&d);
printf("%d,%d,%d\n",d.year,d.month,d.day);
return 0;
}
结果为: