C语言--结构体数组和结构体指针

 结构体是我们自己定义的一种新的数据类型, 同样可以有结构数组和结构指针。 

1.结构体数组

具有相同结构体类型的变量构成的数组,称为结构体数组。与普通数值型数组的不同之处在于每个数组元素都是一个结构体变量,它们都分别包含各个成员项。

  • 定义结构体数组一般形式是
struct 结构体名
{
    成员列表
}数组名[数组长度];

或者:
先声明一个结构体类型,然后再定义结构体数组

结构体类型 数组名[数组长度];

对结构体数组初始化的形式是在定义数组的后面加上:={初始表列};

如:

struct student S1[3]={"Li",0,"Zhang",2"Sun",3};

结构体数组的应用举例

输入三个学生的个人信息 包含学号 姓名和三门学科的成绩 
输出平均成绩最高的学生的学号 姓名 各科成绩以及平均成绩 

#include<stdio.h>


struct Student
{int num;
char name[20];
float score[3];
float aver;
};



void input(struct Student stu[])
{
    //input函数形参为结构体数组,实参为结构体指针。 
    int i;
    printf("请依次输入学生编号,姓名,三个科目成绩:\n");
    for (i=0;i<3;i++)
    {
        scanf("%d %s %f %f %f",&stu[i].num, &stu[i].name, &stu[i].score[0], &stu[i].score[1], &stu[i].score[2]);
        stu[i].aver = (stu[i].score[0]+stu[i].score[1]+stu[i].score[2])/3.0;
    }
}

struct Student max(struct Student stu[])
{
    //max函数形参为结构体数组,实参为结构体指针。 
    int i,m=0;
    for (i = 0;i<3;i++)
    {
        if(stu[i].aver>stu[m].aver) m = i;
    }
    return stu[m];
}

void print(struct Student stud)
{
//print函数形参是结构体变量,实参是结构体变量(是结构体数组元素)。
    printf("成绩最高的学生:\n");
    printf("学号:%d\n 姓名:%s\n 三门成绩:%5.1f,%5.1f,%5.1f\n 平均成绩:%6.2f\n",stud.num,stud.name,stud.score[0],stud.score[1],stud.score[2],stud.aver);
    getchar();
}

int main()
{
    
    struct Student stu[3];
    struct Student *p=stu;//定义结构体指针p,并初始化它让他指向结构体数组stu的首地址。
    input(p);//输入序号,姓名,成绩等数据,存入结构体数组中
    print(max(p));//比较平均成绩,得到平均成绩最大的那个数组
    getchar();
    getchar();
//有些编译器在执行完程序后会自动关闭输出界面,俗称“闪退”,加上getchar();意思是等待用户从键盘输入
//一个按键,这样可以解决闪退问题。

    return 0;
}

运行结果

2.结构体指针

所谓结构体指针就是指向结构体变量的指针,表示的是这个结构体变量占内存中的起始位置,

如果把一个结构体变量的起始地址存放在一个指针变量中,那么,这个指针变量就指向该结构体变量。

定义结构体变量的指针:

//假设已有一个结构体名为Student
struct Student *pStruct
// 结构体类型 * 指针名;

demo:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*1.使用->引用结构体成员 */

int main ()
{

    struct Student
    {
        long num;
        char name[20]; 
        char sex;
        float score;
    };//student={"Girl",2017,'w',2};
    

    struct Student stu;//定义struct Student类型的变量stu
    struct Student *pStruct;//定义指向struct Student类型数据的指针变量pStruct
    pStruct = &stu; //pStruct指向stu
    stu.num=10101;
    strcpy(stu.name,"fan");//对结构体变量的成员赋值
    stu.sex='M';
    stu.score=88;
    printf("-----------the sudent's information----------\n");
    printf("NO.:%ld\nname:%s\nsex%c\nscore:%5.1f\n",stu.num,stu.name,stu.sex,stu.score);

    printf("\nNO.:%ld\nname:%s\nsex%c\nscore:%5.1f\n",(*pStruct).num,(*pStruct).name,(*pStruct).sex,(*pStruct).score);

    printf("\nNO.:%ld\nname:%s\nsex%c\nscore:%5.1f\n",pStruct->num,pStruct->name,pStruct->sex,pStruct->score);


    return 0;
}

(*pStruct).num中的(*pStruct)表示,*pStruct指向结构体变量,(*pStruct).num表示pStruct指向结构体变量中的成员num,注意括号不能省略,因为成员运算符“.”优先于“*”运算符。为了直观和使用方便,C语言允许把(*pStruct).num用pStruct->num来代替,上面的三种表达方式等价。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Student //声明结构体类型Student
{
	int num;
	char name[20]; 
	char sex;
	int age;
};
struct Student stu[5]=
{
    {10101,"Zhou ping",'M',15},//定义结构体数组并初始化
    {10102,"Zhang ping",'M',15},
    {10103,"Liou fang",'F',16},
    {10104,"Cheng ling",'F',17},
    {10105,"Wang ming",'M',15}
};

int main()
{
	struct Student *ps;//定义指向struct Student结构体类型数据的指针变量
	printf("No\tName\t\t\tSex\tage\t\n");
	for(ps=stu;ps<stu+5;ps++)
		printf("%d\t%s\t\t%c\t%d\t\n",ps->num,ps->name,ps->sex,ps->age);
	return 0;
}

如果ps的初始值是stu,即指向stu的第一个元素,ps加1后就指向下一个元素。(++ps)->num和(ps++)->是不一样的

在程序中,定义了Student结构类型的外部数组stu并作了初始化赋值。在main函数内定义ps为指向Student类型的指针。在循环语句for的表达式1中,ps被赋予stu的首地址,然后循环5次,输出stu数组中各成员值。
应该注意的是,一个结构指针变量虽然可以用来访问结构变量或结构数组元素的成员,但是,不能使它指向一个成员。也就是说不允许取一个成员的地址来赋予它。因此,下面的赋值是错误的。
    ps=&stu[1].sex;
而只能是:
    ps=stu;(赋予数组首地址)
或者是:
    ps=&stu[0];(赋予0号元素首地址)

猜你喜欢

转载自blog.csdn.net/weixin_39371711/article/details/81738561