指针和结构体【重点】
指针和结构体【重点】
为什么需要结构体:
解决表示一些复杂的事物,而普通的基本类型无法满足实际要求
什么叫结构体
把一些基本类型整合在一起形成的一个新的复合数据类型
如何定义结构体(3种方式)
// 第一种方式 推荐第一种方式
struct Student
{
int age;
float score;
char sex;
}
// 第二种方式 在定义的同时直接写变量名
struct Student2
{
int age;
float score;
char sex;
} st2;
// 第三种方式 不知道变量什么类型
struct
{
int age;
float score;
char sex;
} st3;
怎么使用结构体变量
1、赋值和初始化
定义的同时可以整体赋初值
如果定义完之后,则只能单个的赋初值
2、 如何取出结构体变量中的每一个成员【重点】
1、结构体变量名.成员名
2、指针变量名->成员名(第二种方式更常用)
指针变量名->成员名 在计算机内部会被转化成 (*指针变量名).成员名的方式来执行
所以说这两种方式是等价的
例子:
// 第一种方式
struct Student
{
int age;
float score;
char sex;
};
int main (void)
{
struct Student st ={80,66.6,'F'}; //初始化 定义的同时赋初值
struct Student *pst = &st; // &st 不能改成 st
pst->age = 88; //第二种方式
st.age = 10; //第一种方式
printf("%d %f\n",st.age,pst->score );
return 0;
}
1、pst->age在计算机内部会被转化为(*pst).age,没有什么为什么,这是->的含义,也是一种硬性规定
2、所以pst->age 等价于 (*pst).age 也等价于 st.age
3、我们之所以知道**pst->age 等价于st.age** , 是因为**pst->age**是**被转化成**了**(*pst).age** 来执行
4、 pst->age 的含义:
**pst 所指向的那个结构体变量中的age这个成员**
3、结构体变量的运算
结构体变量不能相加,不能相减,也不能相互乘除
struct Student
{
int age;
char sex;
char name[100];
}; //分号不能省
struct Student st1,st2
st1+st2 st1*st2 st1/st2 都是错误的
st1 = st2 或者 st2 = st1 都是正确的
4、 结构体变量和结构体变量指针作为函数参数传递的问题
推荐使用结构体指针变量作为函数参数来传递
# include <stdio.h>
# include <string.h>
struct Student
{
int age;
char sex;
char name[100];
}; //分号不能省
void OutputStudent(struct Student ss)
{
printf("%d %c %s\n",ss.age,ss.sex,ss.name );
}
void InputStudent(struct Student *pstu) //pstu只占4个字节,一个字节一个地址
{
pstu->age = 10; // 等价于 (*pstu).age
strcpy(pstu->name,"张三"); // name不能直接赋值,要通过 strcpy 函数
pstu->sex = 'F';
}
// 本函数无法修改主函数 st 的值,所以本函数是错误的
/*
void InputStudent(struct Student stu)
{
stu.age = 10;
strcpy(stu.name,"张三"); // 不能写成 stu.name = "张三"
stu.sex = 'F';
}
*/
int main (void)
{
struct Student st;
InputStudent(&st); //对结构体变量输入 必须发送st的地址
// printf("%d %c %s\n",ss.age,ss.sex,ss.name );
OutputStudent(st); //对结构体变量输出 可以发送 st的地址也可以直接发送 st变量的内容
return 0;
}
5、 动态构造存放学生信息的结构体数组
动态构造一个数组,存放学生的信息,然后按分数排序输出
# include <stdio.h>
# include <malloc.h>
struct Student
{
int age;
float score;
char name[100];
};
int main (void)
{
int len;
struct Student *pArr;
int i,j;
struct Student t;
//动态构造一维数组
printf("请输入学生的个数:\n");
printf("len = ");
scanf("%d",&len);
pArr = (struct Student *)malloc(len * sizeof( struct Student ));
// 输入
for(i=0; i<len; ++i)
{
printf("请输入第%d个学生信息:\n",i+1);
printf("age = ");
scanf("%d",&pArr[i].age );
printf("name = ");
scanf("%s",pArr[i].name ); // name是数组名,本身就已经是数组首元素的地址,所以 pArr[i].name不能改成 &pArr[i].name
printf("score = ");
scanf("%f",&pArr[i].score );
}
printf("\n\n");
// 按学生成绩升序排序 冒泡排序
for (i=0; i<len-1; ++i)
{
for(j=0; j<len-1-i; ++j)
{
if(pArr[j].score > pArr[j+1].score )
{
t = pArr[j]; //互换的是整个结构体
pArr[j] = pArr[j+1];
pArr[j+1] = t;
}
}
}
// 输出
for(i=0; i<len; ++i)
{
printf("第%d个学生信息是:\n",i+1);
printf("age = %d\n",pArr[i].age );
printf("name = %s\n",pArr[i].name );
printf("score = %f\n ",pArr[i].score );
printf("\n");
}
return 0;
}