结构体 :是一种自定义数据结构。
结构体的形式:
struct 类型名
{
结构体;
};
结构体的结尾必须加上分号

结构体的定义以及初始化

struct Student//定义Student数据类型
{
 char name[20];
 int age;
};//定义完成,其地位和内置类型一样
int main
{
	//结构体的定义以及初始化
	struct Student stu1={"zhang",24};
	struct Student stu2;
	struct Student stu3={"liu"};//只初始化一部分,剩余部分为0
}

结构体内可定义结构体, 结构体定义完成后,起作用和C语言中内置的数据类型相同。

struct A
{
 int a;
 double b;
};
struct B
{
 long *c;
 struct A d;//ok  结构体A在之前定义了,可以直接使用
 //struct B e;//error  B还未定义结束,无法确定结构体B的大小
 struct B *f;//ok 指针的内存大小已经固定,可以使用
};
//结构体通过指针调用自身的定义举例
struct Node
{
 int data;
 struct Node *next;
}

对结构体的成员进行访问:结构体普通变量通过 “.” 访问其成员

int main()
{
 struct Student stu={"liu",20};
 //修改年龄
 stu.age=18;
 //修改姓名
 strcpy(stu.name,"zhang");
 //输出stu的信息
 printf("age=%d  ,  name=%s\n",stu.age,stu.name);
}

**通过指针对结构体进行访问:**结构体指针变量通过 “->”访问其成员

int main()
{
 struct Student stu={"liu",20};
 struct Student *ps=&stu;
 //修改年龄
 *ps.age=18;//error  优先级的问题  .的优先级大于*  应该是:(*ps).age=18; 
 (*ps).age=18; //ok
 ps->age=18;//ok
}

加强对 . 和 -> 的理解:

struct A
{
 int a;
 double *b;
};
struct B
{
 long *c;
 struct A d;
};
//通过变量aa或者bb,访问其各自的成员
int main()
{
 struct B aa;
 struct B *bb=&aa; 
 aa.c;
 aa.d;
 aa.d.a;
 aa.d.b;
 bb->c;
 bb->d;
 bb->d.a;
 bb->d.b;
}

结构体作为参数进行传递时,使用指针进行传递,减小传参时浪费的空间资源

//void Show(struct Student stu)//设计不好,传递的数据太大(实参24个字节),使用指针
void Show(const struct Student *p)
{
 printf("%s,%d\n",p->name,p->age);
}
int main()
{
 struct Student stu={"liu",18};
 Show(&stu);
 return 0;
}

通过数组访问结构体

void Show(const struct Student *p,int len)
{
 for(int i=0;i<len;i++)
 {
  printf("%s  %d\n",p[i].name,p[i].age);
  //printf("%s  %d\n",*(p+i)->name,*(p+i)->age);//ok  指针
 }
 printf("\n");
}
int main()
{
 struct Student stu[3]={"zhang",18,"liu",18,"wang",18};
 stu[2].age=20;
 Show(stu,sizeof(stu)/sizeof(stu[0]));
 return 0;
}

结构体的应用实例:有3个候选人,每个选民只能投票1个人,要求编一个统计票选的程序,先后输入备选人的名字,最后输出每个人投票结果。

#include<stdio.h>
#include<string.h>
struct Person
{
 char name[20];//候选人名字
 int count;//票数
};
//统计票数
void Ticket(struct Person *arr,int len)
{
 char name[20];//读票
 for(int i=0;i<5;i++)//模拟5个选民
 {
  scanf("%s",name);
  for(int j=0;j<len;j++)//遍历候选人列表,给名字相同的票数加1
  {
   if(strcmp(name,arr[j].name))
   {
    arr[j].count++;
    break;
   }
  }
 }
}
void Show(const struct Person *arr,int len)
{
 for(int i=0;i<len;i++)
 {
  printf("%s得得票数为%d\n",arr[i].name,arr[i].count);
 }
}
int main()
{
 struct Person arr[]={"zhang",0,"liu",0,"yao",0};
 Ticket(arr,sizeof(arr)/sizeof(arr[0]));
 Show(arr,sizeof(arr)/sizeof(arr[0]));
 return 0;
 }

C中有两个自带的符号,分别为 [] 和 -> 。举例:p[i]==(p+i) ; p->age==(*p).age
将分数由高到低输出的学生的信息:

#include<stdio.h>
#include<string.h>
struct Student
{
 int id;//学号
 char name[20];//姓名
 int score;//分数
};
//从键盘读取学生信息
void Input(const struct Student *arr,int len)
{
 for(int i=0;i<len;i++)
 {
  scanf("%d %s %d",&arr[i].id,arr[i].name,&arr[i].score);
 }
}
//学生分数由高到低排序
void Sort( struct Student *arr,int len)
{
 struct Student tmp;
 for(int i=0;i<len;i++)
 {
  for(int j=0;j+1<len-i;j++)//小心j+1越界
  {
   if(arr[j].score<arr[j+1].score)
   {
    tmp=arr[j];
    arr[j]=arr[j+1];
    arr[j+1]=tmp;
   }
  }
 }
}
void Show(const struct Student *arr,int len)
{
 for(int i=0;i<len;i++)
 {
  printf("学号为%d的学生%s得分为%d\n",arr[i].id,arr[i].name,arr[i].score);
 }
}
int main()
{
 struct Student arr[5];
 Input(arr,sizeof(arr)/sizeof(arr[0]));
 Sort(arr,sizeof(arr)/sizeof(arr[0]));
 Show(arr,sizeof(arr)/sizeof(arr[0]));
 return 0;
 }