目录
结构成员的类型 结构的成员可以是标量、数组、指针,甚至是其他结构体。
1.1 结构体的声明
我们知道c语言中有很多类型:char short int long float double类型,但这些类型并不能表示复杂对象
描述学生:姓名,年龄,性别,成绩...
结构的基础知识 结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。
//结构体申明:
struct(关键字) tag(名字)
{
member-list;(成员变量)
}variable-list;(变量列表,可写可不写)
//申明一个学生结构体
struct Stu
{
char name[20];//名字
int age;//年龄
char sex[8];//性别
float score;//成绩
}s1,s2,s3; //分号不能丢s1,s2,s3是通过struct Stu类型创建的变量
//s1,s2,s3是全局变量
int main()
{
struct Stu s4; //局部变量
}
struct Stu 才是结构体类型,不能随便省略struct,我们可以使用typedef(类型重定义)
typedef struct Stu
{
char name[20];//名字
int age;//年龄
char sex[8];//性别
float score;
}Stu;//(对整个上面类型重新起名字,不能再创建列表)
int main()
{
Stu s6; //局部变量
}
结构成员的类型 结构的成员可以是标量、数组、指针,甚至是其他结构体。
1.2 结构体变量的定义和初始化
struct Point
{
int x;
int y;
}p1 = {10, 15};//定义变量p1并初始化
struct S
{
char c;
struct Point sp;
double d;
char arr[20];
};
int main()
{
struct Point p = { 100, 200 };//初始化
struct S ss = { 'w', {100,20}, 5.5, "hello"};
return 0;
}
2.1 结构体成员的访问
结构变量的成员是通过结构成员操作符(.)访问
struct Point
{
int x;
int y;
}p1 = {10, 15};//定义变量p1并初始化
struct S
{
char c;
struct Point sp;
double d;
char arr[20];
};
int main()
{
struct Point p = { 100, 200 };//初始化
struct S ss = { 'w', {100,20}, 5.5, "hello"};
printf("%c\n", ss.c);//结构体对象.结构体成员
printf("%c\n", ss.sp.x,ss.sp.y);
printf("%c\n", ss.d);
printf("%c\n", ss.arr);
return 0;
}
2.2 结构体指针(下面写法哪个好)
struct Point
{
int x;
int y;
}p1 = {10, 15};
struct S
{
char c;
struct Point sp;
double d;
char arr[20];
};
void print1(struct S s)//打印struct S类型的变量,s是一份临时拷贝
{
printf("%c\n", s.c);
printf("%d %d\n", s.sp.x, s.sp.y);
printf("%lf\n", s.d);
printf("%s\n", s.arr);
}
void print2(struct S* ps)//指针,传过来的是ss地址
{
printf("%c\n", ps->c);
printf("%d %d\n", ps->sp.x, ps->sp.y);
printf("%lf\n", ps->d);
printf("%s\n", ps->arr);
}
int main()
{
struct Point p = {100, 200};
struct S ss = { 'w', {100,20}, 5.5, "hello"};
//ss.c = 'b';可以改变量
//ss.sp.x = 1000;
//ss.sp.y= 2000;
//ss.d = 3.14;
//strcpy(ss.arr, "world");//strcpy字符串拷贝
print1(ss);//打印struct S类型的变量
print2(&ss);//拿到ss
return 0;
}
struct S类型的变量创建了两份,参数是需要压栈的。 如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能下降。
print2只传过去ss地址,大小4/8个字节,节省空间
. 结构体变量.结构体成员
-> 结构体指针->结构体成员
结构体传参的时候,要传结构体的地址。
3.1 结构体作业练习
struct student
{
int num;
char name[32];
float score;
}stu;
下面的叙述不正确的是:( )
A.struct 是结构体类型的关键字
B.struct student 是用户定义的结构体类型
C.num, score 都是结构体成员名
D.stu 是用户定义的结构体类型名
A:正确,在C语言中需要自定义类型时,要用到struct关键字
B:正确:在C语言中,用struct定义的结构体,定义结构体类型变量时,需要用struct student
C:正确:结构体中的变量名称,称之为结构体的成员
D:错误:stu是定义的结构体类型变量,不是名称,如果想要让stu为结构体类型名称时,必须在结构体定义时添加 typedef关键字
因此:选择D
3.2 下面程序的输出结果是
struct stu
{
int num;
char name[10];
int age;
};
void fun(struct stu *p)
{
printf(“%s\n”,(*p).name);
return;
}
int main()
{
struct stu students[3] = {
{9801,”zhang”,20},
{9802,”wang”,19},
{9803,”zhao”,18}
};
fun(students + 1);
return 0;
}
在main函数中先定义了一个stu结构体类型的数组students,students指向结构体的起始位置,students+1表示该数组中的第一个元素,因此fun的形参实际指向的是students数组中的第一个元素,故打印的是wang