c语言结构体概述

**

结构体类型

**
一,结构体类型
结构体:是由不同类型(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;
}
  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值