**
结构体类型
**
一,结构体类型
结构体:是由不同类型(int,char,float等等)的数据项组合而成的复合数据类型。其中的数据项称为结构体的成员。
以“struct”关键词定义一个结构体变量。
二,结构体的定义
定义结构体的一般形式:
struct 结构名
{
类型 成员名1;
类型 成员名2;
类型 成员名3;
…
};
note:成员可以属于另一个结构体变量。
例如:
struct date
{
int month;
int day;
int year;
};
struct student
{
int num;
char name[20];
char sex;
int age;
student date birthday; //成员birthday属于struct date类型
};
定义一个结构变量的三种方式:
1.先定义结构体类型在定义结构体变量
struct student stu1,stu2;
stu1,stu2为结构体变量,即它们都具有struct student 定义的结构。
//例:
struct student stu1
{
int num;
char name[20];
int age;
};
若在程序开头预定义一个符号常量来代表一个结构体类型,即:
#define STUDENT struct student
这是结构体类型的定义可改写为:
STUDENT
{
int num;
char name[20];
int age;
};
//然后用STUDENT定义结构变量
STUDENT stu1,stu2;
2.在声明类型的同时定义变量
一般形式:
struct 结构体名
{
类型 成员名1;
类型 成员名2;
…
}结构变量名表;
//例:
struct student
{
int num;
char name[20];
int age;
}stu1,stu2;
3.不指定类型名而直接定义结构体类型变量
一般形式:
struct
{
类型 成员名1;
类型 成员名2;
类型 成员名3;
…
}结构变量名表;
note:
a.结构体类型与结构体变量是不同的概念,在编译时,对结构体类型不分配存储空间,只对结构变量分配内存空间
b.结构体类型中的成员名可以和程序中的变量名相同,但二者代表不同对象
c.结构体变量中的成员(即“域”),可单独使用
d.结构体是一种数据类型
三,结构体变量引用规则
1.成员的访问:
访问成员时,用操作符“ . ”,格式为:
结构体变量名.成员名
(不能将一个结构体变量作为一个整体进行输入和输出)
2.结构体变量的成员可以进行各种运算。比如:
stu1.number++; (自加运算)
stu2.score=stu1.score;(赋值运算)
sum=stu1.score+stu2.score;(加法运算)
3.可以引用成员的地址,也可以引用结构体变量的地址。如:
scanf("%d",&stu.number);
printf("%d",stu.number);
四,结构体变量的初始化
1.在定义结构体类型的同时进行结构体变量的定义及初始化
#include<stdio.h>
#include<stdlib.h>
struct addr
{
char name[20];
char address[20];
long int zip;
long int phone;
}a = {"ren","shaanxi",10000,12345}; //!!!
int main()
{
printf("name:%s\naddress:%s\nzip:%ld\nphone:%ld\n", a.name, a.address, a.zip, a.phone);
system("pause");
return 0;
}
2.先定义结构体类型,在进行结构体变量的定义及初始化
#include<stdio.h>
#include<stdlib.h>
struct addr
{
char name[20];
char address[20];
long int zip;
long int phone;
};
struct addr a = { "ren", "shaanxi", 10000, 12345 }; //!!!
int main()
{
printf("name:%s\naddress:%s\nzip:%ld\nphone:%ld\n", a.name, a.address, a.zip, a.phone);
system("pause");
return 0;
}
结构体数组
一个结构体变量只能存放一条信息,要存放多条记录,需要使用结构体数组。它的特点是:每个数组元素都是结构体类型,他们都包括各个成员。
一,结构体数组的定义
定义结构体数组的一般形式:
1.struct 结构体名
{
成员表列;
}数组名[数组长度];
for example:
struct addr
{
char name[20];
char address[20];
long int phone;
}stu[5];
2.结构体类型;
数组名[数组长度];
for example:
struct addr
{
char name[20];
char address[20];
long int phone;
};
struct addr stu[5];
or:
struct
{
char name[20];
char address[20];
long int phone;
};
struct addr stu[5];
二,结构体数组的初始化
形式:
struct 结构体名
{
成员表列;
}数组名[数组元素个数]={初值表列};
for example:
struct addr
{
char name[20];
char address[20];
long int phone;
}stu[2]={{"a","add",110,},{"b","ass",120}};
三,结构体数组的应用举例
例:有n个学生信息(学号,姓名,成绩),要求按成绩从高到低输出学生信息。
#include<stdio.h>
#include<stdlib.h>
struct student
{
int num;
char name[20];
float score;
};
struct student stu[5]={{1,"ren",99},{2,"wang",89.5},{3,"zhang",99.5},{4,"liu",100},{5,"zhao",77.5}}; //定义结构体数组并初始化
int main()
{
struct student temp; //用作交换的临时变量
int n=5;
int i,j,k;
printf("The order if:\n");
for(i=0;i<4;i++)
{
k=i;
for(j=i+1;j<5;j++)
{
if(stu[j].score>stu[k].score)
{
k=j;
temp=stu[k]; //stu[k]和stu[i]交换
stu[k]=stu[i];
stu[i]=temp;
}
}
}
for(i=0;i<5;i++)
{
printf("%d %s %4.2f\n",stu[i].num,stu[i].name,stu[i].score); //输出
}
system("pause");
return 0;
}
结构体指针
结构体指针就是指向结构体变量的指针,一个结构体变量的起始地址就是这个结构体变量的指针。
一,指向结构体变量的指针
结构体指针要求先定义,后使用。
1.步骤:
(1).先定义结构体:
struct 结构体名
{
…
}结构体变量表;
(2).定义指向结构体变量的指针变量:
struct 结构体名 *p;
或者:p=&结构体变量;
2.引用形式如下:
a. 指针变量->成员;
b. 结构体变量.成员名;
c. (*p).成员名;
3.与指向运算符“->”相关的运算:
表达式 | 运算结果 |
---|---|
p->n | 得到p指向的结构体变量中的成员n的值 |
p->n++ | 得到p指向的结构体变量中的成员n的值 ,用完该值后使它加1 |
++p->n | 得到p指向的结构体变量中的成员n的值使之加1(先加) |
4.for example:
//用结构体指针变量输出结构体变量中成员的信息。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct student
{
int num;
char name[20];
char sex;
float score;
};
struct student stu;
struct student *p=&stu; //结构体指针指向结构体数据
int main()
{
stu.num = 1;
strcpy(stu.name, "zhang san"); //字符串复制函数给stu.name赋值
stu.sex = 'm';
stu.score = 99.5;
printf("第一次:\n%d\n%s\n%c\n%3.1f\n", stu.num, stu.name, stu.sex, stu.score);
printf("第二次:\n%d\n%s\n%c\n%3.1f\n", p->num, p->name, p->sex, p->score);
printf("第三次:\n%d\n%s\n%c\n%3.1f\n", (*p).num, (*p).name, (*p).sex, (*p).score); //三次打印结果相同
system("pause");
return 0;
}
二,指向结构体数组的指针
for example:
//输出结构体数组中的学生信息
#include<stdio.h>
#include<stdlib.h>
struct student
{
int num;
char name[20];
char sex;
float score;
};
struct student stu[2] = { { 1, "zhangsan", 'm', 99.8 }, {2,"lisi",'m',98.5} }; //定义结构体数组并初始化
int main()
{
struct student *p=stu; //使p指向结构体数组的首元素
for (p; p < stu + 2; p++)
{
printf("%d\n%s\n%c\n%3.1f\n", p->num, p->name, p->sex, p->score);
}
system("pause");
return 0;
}
三,用指向结构体的指针做函数参数
将一个结构体变量的值传给另一个函数时的方法:
1.用结构体变量的成员做参数。
2.用结构体变量做实参。(需一个个传递全部成员,麻烦,不建议使用)
3.用结构体指针做参数。将结构体变量的地址传给形参。(常用)
for example:
//有3个学生的信息,要求输出平均成绩最高的学生的信息(包括学号,名字,三门课成绩和平均分)
#include<stdio.h>
#include<stdlib.h>
struct student
{
int num;
char name[20];
float score[3]; //三门课的成绩
float aver;
};
void input(struct student stu[]) //输入学生信息
{
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[]) //找平均成绩最高的学生
{
int i, m = 0; //m存放成绩最高的学生在数组中的序号
for (i = 0; i < 3; i++)
{
if (stu[i].aver>stu[m].aver) //找出成绩最高的学生在数组中的序号
{
m = i;
}
}
return stu[m];
}
void print(struct student stud) //输出学生信息
{
printf("\n最高成绩的学生是:\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);
}
int main()
{
struct student stu[2];
struct student *p = stu;
input(p); //调用input函数
print(max(p)); //调用print函数,以max函数的返回值作为实参
system("pause");
return 0;
}
结构体和函数之间的参数使用(重点+难点):
1.用结构体变量成员作实参:属于“值传递”方式,注意实参和形参的类型保持一致。
2.用结构体变量作实参 :属于“值传递”方式,形参必须是与实参同类型的结构体变量。
缺点:①这种传递方式在空间和时间上开销比较大;②在被调用函数期间改变了形参,并不能改变主函数中的实参值。
3.用指向结构体变量(或数组元素)的指针作实参,将结构体变量(或数组元素)的地址传给形参。
#include<stdio.h>
#include<stdlib.h>
struct stud
{
long int num;
float score;
};
void fun1(struct stud t)
{
t.num = 2000101;
t.score = 71.0;
}
void fun2(struct stud t[])
//void fun2(struct stud &t) //&为引用
{
t[0].num = 3000101; /*注意结构体数组元素的成员的引用形式*/
t[0].score = 81.0;
t[1].num = 3000102;
t[1].score = 82.0;
}
void fun3(struct stud *t)
{
t->num = 4000101; /*注意通过结构体指针变量引用成员的具体形式*/
(*t).score = 92.0;
}
void main()
{
struct stud a[2] = {{ 1000101, 61.0 }, { 1000102, 62.0 }};
struct stud b = a[0];
int i;
printf("原有的值: \nnum:%ld\t\tscore:%.1f\n", b.num, b.score);//显示结构体变量b的成员的原有值
fun1(b); // 结构体变量作为函数参数(未变)
printf("结构体变量作为函数参数时的结果值:\nnum:%ld\t\tscore:%.1f\n ", b.num, b.score);
fun3(&b); //结构体变量的指针作为函数的参数(已改变)
printf("结构体变量的指针作为函数的参数时的结果值:\nnum:%ld\t\tscore:%.1f\n ", b.num, b.score);
printf("原结构体数组的值:\n");
for (i = 0; i < 2; i++)
{
printf("num:%ld\t\tscore:%.1f\n ", a[i].num, a[i].score);
}
printf("结构体数组作为函数的参数时的结果值:\n");
fun2(a); //结构体数组作为函数的参数(已改变)
for (i = 0; i < 2; i++)
{
printf("num:%ld\t\tscore:%.1f\n ", a[i].num, a[i].score);
}
system("pause");
return 0;
}