结构体
结构体类型概念
结构体:一种构造类型,由若干成员组成,成员可以是基本数据类型,也可以是构造类型
struct 结构体名
{
成员列表
};
结构体变量定义
定义:
方式一:先声明结构体类型,再定义变量
struct Product product1;
struct Product product2;
//Product是结构体类型
//product1、product2是结构体变量名
结构体变量的定义不仅要求指定变量为结构体类型,而且要求指定为某一特定的结构体类型。而基本变量的定义只需要指定类型即可。
定义结构体变量后,系统会为其分配内存单元,大小为定义成员列表的大小总和。
方式二:在声明结构类型的同时定义变量
struct Product{
//成员列表
}product1,product2;
方式三:直接定义结构体类型变量
struct{
//成员列表
}product1,product2;
类型与变量不同,在编译时,计算机不会对类型进行分配内存,只对变量分配内存
结构体变量的引用
对结构体变量进行引用时,不能直接将结构体变量作为一个整体进行输入和输出,在进行 输出时需要对结构体变量进行赋值、存取或运算。赋值方法:结构变量名.成员名=值。
如果成员变量本身是结构体变量,则需要一级一级的赋值,即智能对最低一级进行赋值、运算、存取
#include #include struct test{
int num;
char name;
}test01;
int main()
{
scanf("%d",&test01.num);
printf("%d",test01.num);
return 0;
}
结构体类型的初始化
#includestruct Student/*学生结构*/
{
char cName[20];/*姓名*/
char cSex;/*性别*/
int iGrade;/*年级*/
} student1={"HanXue",'W',3};/*定义变量并设置初始值*/
int main()
{
struct Student student2={"WangJiasheng",'M',3};/*定义变量并设置初始值*/
/*将第一个结构体中的数据输出*/
printf("the student1's information:\n");
printf("Name: %s\n",student1.cName);
printf("Sex: %c\n",student1.cSex);
printf("Grade: %d\n",student1.iGrade);
/*将第二个结构体中的数据输出*/
printf("the student2's information:\n");
printf("Name: %s\n",student2.cName);
printf("Sex: %c\n",student2.cSex);
printf("Grade: %d\n",student2.iGrade);
return 0;
}
结构体数组
定义结构体数组
struct 结构体名
{
成员列表
}数组名[];
struct Student{
char cName[20];
int iNumber;
char cSex;
int iGrade;
}student[5];
初始化结构体数组
#includestruct Student/*学生结构*/
{
char cName[20];/*姓名*/
int iNumber;/*学号*/
char cSex;/*性别*/
int iGrade;/*年级*/
} student[5]={{"WangJiasheng",12062212,'M',3},
{"YuLongjiao",12062213,'W',3},
{"JiangXuehuan",12062214,'W',3},
{"ZhangMeng",12062215,'W',3},
{"HanLiang",12062216,'M',3}};/*定义数组并设置初始值*/
int main()
{
int i;/*循环控制变量*/
for(i=0;i<5;i++)/*使用for进行5次循环*/
{
printf("NO%d student:\n",i+1);/*首先输出学生的名次*/
printf("Name: %s, Number: %d\n",student[i].cName,student[i].iNumber);/*使用变量i做下标,输出数组中的元素数据*/
printf("Sex: %c, Grade: %d\n",student[i].cSex,student[i]. iGrade);
printf("\n");/*空格行*/
}
return 0;
}
结构体指针
定义:结构体类型 *指针名
引用方式1:点运算符
#includeint main()
{
struct Student/*学生结构*/
{
char cName[20];/*姓名*/
int iNumber;/*学号*/
char cSex;/*性别*/
int iGrade;/*年级*/
}student={"SuYuQun",12061212,'W',2};/*对结构变量进行初始化*/
struct Student *pStruct;/*定义结构体类型指针*/
pStruct=&student;/*指针指向结构体变量*/
printf("-----the student's information-----\n");/*消息提示*/
printf("Name: %s\n",(*pStruct).cName);/*使用指针引用变量中的成员*/
printf("Number: %d\n",(*pStruct).iNumber);
printf("Sex: %c\n",(*pStruct).cSex);
printf("Grade: %d\n",(*pStruct).iGrade);
return 0;
}
引用方式2:指向运算符
注意:p->i; //表示指向的结构体变量中成员 i 的值
p->i++; //表示指向结构体成员变量中 i 值,在使用后该值+1;
++p->i; //表示指向结构体成员变量 i 的值加1后进行使用。
(++p)->i; //表示指向结构体成员变量 i 的下一个元素的地址,然后取得该元素的值
(p++)->i; //表示先取得当前元素的成员值,在使得指针p指向下一个元素的地址
#include#includestruct Student/*学生结构*/
{
char cName[20];/*姓名*/
int iNumber;/*学号*/
char cSex;/*性别*/
int iGrade;/*年级*/
}student;/*定义变量*/
int main()
{
struct Student *pStruct;/*定义结构体类型指针*/
pStruct=&student;/*指针指向结构体变量*/
strcpy(pStruct->cName,"SuYuQun");/*将字符串常量复制到成员变量中*/
pStruct->iNumber=12061212;/*为成员变量赋值*/
pStruct->cSex='W';
pStruct->iGrade=2;
printf("-----the student's information-----\n");/*消息提示*/
printf("Name: %s\n",student.cName);/*使用变量直接输出*/
printf("Number: %d\n",student.iNumber);
printf("Sex: %c\n",student.cSex);
printf("Grade: %d\n",student.iGrade);
return 0;
}
结构体作为函数参数
1、使用结构体变量作为函数的参数
void Display(struct Student stu);
在形参的位置使用结构体变量,但在函数调用期间,形参也要占用大量的内存,这种方式在时间和空间上的消耗都很大
#includestruct Student/*学生结构*/
{
char cName[20];/*姓名*/
float fScore[3];/*分数*/
}student={"SuYuQun",98.5f,89.0,93.5f};/*定义变量*/
void Display(struct Student stu)/*形参为结构体变量*/
{
printf("-----Information-----\n");/*提示信息*/
printf("Name: %s\n",stu.cName);/*引用结构成员*/
printf("Chinese: %.2f\n",stu.fScore[0]);
printf("Math: %.2f\n",stu.fScore[1]);
printf("English: %.2f\n",stu.fScore[2]);
/*计算平均分数*/
printf("Average score:%.2f\n",(stu.fScore[0]+stu.fScore[1]+stu.fScore[2])/3);
}
int main()
{
Display(student);/*调用函数,结构变量作为实参进行传递*/
return 0;
}
2、使用指向结构体变量的指针作为函数参数
#includestruct Student/*学生结构*/
{
char cName[20];/*姓名*/
float fScore[3];/*分数*/
}student={"SuYuQun",98.5f,89.0,93.5f};/*定义变量*/
void Display(struct Student* stu)/*形参为结构体变量的指针*/
{
printf("-----Information-----\n");/*提示信息*/
printf("Name: %s\n",stu->cName);/*使用指针引用结构体变量中的成员*/
printf("English: %.2f\n",stu->fScore[2]);
stu->fScore[2]=90.0f;/*更改成员变量的值*/
}
int main()
{
struct Student* pStruct=&student; /*定义结构体变量指针*/
Display(pStruct);/*调用函数,结构变量作为实参进行传递*/
printf("Changed English: %.2f\n",pStruct->fScore[2]);/*输出成员的值*/
return 0;
}
3、使用结构体变量的成员作为函数参数
void Display(student.fscore[0]);
包含结构体的结构
#includestruct date/*时间结构*/
{
int year;/*年*/
int month;/*月*/
int day;/*日*/
};
struct student/*学生信息结构*/
{
char name[30];/*姓名*/
int num;/*学号*/
char sex;/*性别*/
struct date birthday;/*出生日期*/
}student={"SuYuQun",12061212,'W',{1986,12,6}};/*为结构变量初始化*/
int main()
{
printf("-----Information-----\n");
printf("Name: %s\n",student.name);/*输出结构成员*/
printf("Number: %d\n",student.num);
printf("Sex: %c\n",student.sex);
printf("Birthday: %d,%d,%d\n",student.birthday.year,
student.birthday.month,student.birthday.day);/*将成员结构体数据输出*/
return 0;
}
因为date成员变量本身是结构体,则在使用的时候需要用大括号将date本身包含的成员变量扩起来
共用体
union 共用体名
{
成员列表
}变量列表;
#includeunion DataUnion/*声明共用体类型*/
{
int iInt;/*成员变量*/
char cChar;
};
int main()
{
union DataUnion Union;/*定义共用体变量*/
Union.iInt=97;/*为共用体变量中成员赋值*/
printf("iInt: %d\n",Union.iInt);/*输出成员变量数据*/
printf("cChar: %c\n",Union.cChar);
Union.cChar='A';/*改变成员的数据*/
printf("iInt: %d\n",Union.iInt);/*输出成员变量数据*/
printf("cChar: %c\n",Union.cChar);
return 0;
}
在程序中改变共用体中一个成员的值,其他成员也会随之改变。当给某个特定的成员进行赋值时,其他成员的值也会有一致的含义,因为它们每个二进制位都被新值所覆盖。
共用体变量的初始化
对于共用体变量初始化时,只需要一个初始化值就够了,其类型必须与共用体的第一个成员的类型相一致
#includeunion DataUnion/*声明共用体类型*/
{
int iInt;/*成员变量*/
char cChar;
};
int main()
{
union DataUnion Union={97};/*定义共用体变量,并进行初始化*/
printf("iInt: %d\n",Union.iInt);/*输出成员变量数据*/
printf("cChar: %c\n",Union.cChar);
return 0;
}
如果共用体中的第一个成员是结构体类型,则初始化值可以包含多个用于初始化该结构的表达式
①对于共用体同一内存中可以存放几种不同的数据类型,但是每次只能存放一种,而不能同时存放所有的类型,即只有一个成员变量起作用。
②共用体中起作用的是最后一个放进去的成员,存放入新的成员后,原成员就失去作用
③共用体变量的地址和其它各成员的地址是一样的
④不能对共用体变量名赋值,要求不能用 变量名来得到一个值。