专升本C语言——第九章

定义和使用结构体变量

自己建立结构体类型

由不同数据组成的组合型的数据类型,它称为结构体(structre)

声明一个结构体类型的一般形式为

struct 结构体名
{
    
    成员表列}

结构体类型的名字是由一个关键字struct和结构体名组合而成的(例如 struct Student)。结构体名是由用户指定的,又称“结构体标记”,以区别于其他结构体类型。

花括号内是该结构体所包含的的子项,称为结构体的成员(member),

对各成员进行类型声明

类型名 成员名;

成员表列也称为域表,每一个成员是结构体中的一个域,成员命名规则与变量名相同

结构体并非只有一种,而是可以设计出许多中结构体类型

成员可以属于另一个结构体类型

//例如:
struct Date		//声明一个结构体类型struct Date
{
	int month;	//月
	int day;	//日
	int year;	//年
}
struct Student				//声明一个结构体类型struct Student
{
	int num;
	char name[20];
	char sex;
	int age;
	struct Data birthday;	//成员birthday属于struct Date类型
	char addr[30];
}

定义结构体类型变量

先声明结构体类型,再定义该类型的变量

例如:
struct Student student1,student2;//定义了student1,student2为struct Student类型的变量,student1和student2具有struct Student类型的结构

在定义了结构体变量后,系统会为之分配内存单元。根据结构体类型中包含的成员情况,在Visual C++中占63个字节(4+20+1+4+4+30=63)

计算机对内存的管理是以“字”为单位的(许多计算机系统以4个字节为一个“字”)。如果在一个“字”中只存放了一个字符,虽然只占一个字节,但该“字”中的其他3个字节不会接着存放下一个数据,而会从下一个“字”开始存放其他数据,因此在用sizeof运算符测试struct1的长度时,得到的不是理论值63,必然是4的倍数

在声明类型的同时定义变量

例如:
struct Student
{
    
    
	int num;
	char name[20];
	char sex;
	int age;
	float score;
	char addr[30];
}student1,student2;

它的作用和第一种方法相同,但是在定义struct Student类型的同时定义两个struct Student类型的变量student1,student2。

这种定义方法的一般形式为

struct 结构体名
{
    
    
	成员表列
}变量名表列;

声明类型和定义放在一起进行,能直接看到结构体的结构,比较直观,在写小程序时用此方式比较方便,但写大程序时,往往要求对整型的声明和变量的定义分别放在不同的地方,以便程序结构清晰,便于维护,所以一般不多用这种方式

不指定类型名而直接定义结构体类型变量

其一般形式为

struct
{
    
    
	成员表列
}变量名表列;

指定了一个无名的结构体类型,它没有名字(不出现结构体名)。虽然不能再以此结构体类型去定义其他变量,这种方式用得不多

  1. 说明:
    结构体类型和结构体变量是不同的概念。只能对变量赋值、存放或预算,而不能对一个类型赋值、存取或与运算。在编译时,对类型是不分配空间的,只对变量分配空间
  2. 结构体类型中的成员可以与程序中的变量名相同,但二者不代表同一对象。例如,程序中可以另定义一个变量num,它与struct Student中的num是两回事,互不干扰
  3. 对结构体变量中的成员(即“域”)可以单独使用,它的作用与地位相当于普通变量

结构体变量的初始化和引用

在定义结构体变量时,可以对它初始化,即赋初始值,然后可以引用这个变量

//例如:
//把一个学生的信息(包括学号、名字、性别、地址)放在同一个结构体变量中,然后输出这个学生的信息
#include<stdio.h>
int main()
{
    
    
	struct Student		//声明结构体类型struct Student
	{
    
    
		long int num;	//以下四行为结构体的成员
		char name[20];
		char sex;
		char addr[20];	//定义结构体变量a并初始化
	}a = {
    
     10101,"Li Lin",'M',"123 beijing Road" };
	printf("NO.:%ld\nname:%s\nsex;%c\naddress:%s\n", a.num, a.name, a.sex, a.addr);
	return 0;
}

运行结果:

NO.:10101
name:Li Lin
sex;M
address:123 beijing Road

在定义结构体变量时可以对它的成员初始化。初始化列表是用花括号括起来的一些常量,这些常量依次赋给结构体变量中的各成员

可以引用结构体变量中的成员的值,引用方式为

结构体变量名.成员名
sudent.num=10010;//"."是成员运算符,它在所有运算符中优先级最高

如果成员本身又属于一个结构体类型,则要用若干个成员运算符,一级一级地找到最低的一级的成员,只能对最低级的成员进行赋值或存取以及运算

引用方式:

student.num					//结构体变量student1中的成员num
student.birthday.mother		//结构体变量student1中的成员的birthday中的的成员的month

对结构体变量的成员名可以像普通变量一样进行各种运算(根据其类型决定可以进行的运算)

student2.score=studen1.score;		//赋值运算
sum=student1.score+student2.score;	//加法运算
student.age++;						//自加运算

同类的结构体变量可以互相赋值

student1=student2;		//假设student1和student2已定义为同类型的结构体变量

可以引用结构体变量成员的地址,也可以引用结构体变量的地址

scanf("%d",&student1,num);	//输入&student1.num的值
printf("%o",&student1);		//输出结构体变量&student1的首地址

说明:结构体变量的地址主要用作函数参数,传递结构体变量的地址

使用结构体数组

定义结构体数组

定义结构体数的一般形式是

struct 结构体名
{
    
    成员表列} 数组名[数组长度]//先声明一个结构体类型,然后再用此类型定义结构体数组:
struct Person leader[3];	//leader是结构体数组名

对结构体数组初始化的形式是定义数组的后面加上:

={初值表列};

struct Person leader[3]={
    
    "Li",0,"Zhang",0,"Sun",0};

结构体指针

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

指向结构体变量的指针

指向结构体对象的指针变量既可以指向结构体变量,也可指向结构体数组中的元素,指针变量的基类型必须与结构体变量的类型相同

struct Student *pt;		//pt可以指向struct Student类型的变量或数组元素
//例如:

#include<stdio.h>
#include<string.h>
int main()
{
    
    
	struct Student
	{
    
    
		long num;
		char name[20];
		char sex;
		float score;
	};
	struct Student stu_1;			//定义struct Student 类型的变量stu_1
	struct Student* p;				//定义指向struct Student类型数据的指针变量p
	p = &stu_1;						//p指向stu_1
	stu_1.num = 10101;				//对结构体变量的成员赋值
	strcpy(stu_1.name, "li lin");	//用字符串复制函数给stu_1.name赋值
	stu_1.sex = 'M';
	stu_1.score = 89.5;
	printf("No.%ld\nname:%s\nsex:%c\nscore:%5.1f\n", stu_1.num, stu_1.name, stu_1.sex, stu_1.score);
	printf("No.%d\nnmae:%s\nsex:%c\nscore:%5.1f\n", (*p).num, (*p).name, (*p).sex, (*p).score);
	return 0;
}

运行结果:

No.10101
name:li lin
sex:M
score: 89.5
No.10101
nmae:li lin
sex:M
score: 89.5

(*p).name等价于p->name。->称为指针运算符

如果p指向一个结构变量stu,以下3种用法等价

stu.成员名(如stu.num);
(*p).成员名((*p).num);
p->成员名(如p->num);

指向结构体数组的指针

可以用指针变量指向结构体数组的元素

#include<stdio.h>
struct Student//声明结构体类型struct Student
{
    
    
	int num;
	char name[20];
	char sex;
	int age;
};
struct Student stu[3] = {
    
     {
    
    10101,"li lin",'M',18}, {
    
    10102,"zhang fang",'M',19},{
    
    10104,"wang min",'F',20} };//定义结构体数组并初始化
int main()
{
    
    
	struct Student* p;//定义指向struct Student结构体变量的指针变量
	printf("No.    Name                sex  age\n");
	for (p = stu; p < stu + 3; p++)
		printf("%5d %-20s %2c %4d\n", p->num, p->name, p->sex, p->age);//输出结果
	return 0;
}
//(++p)-> 先使p自加1,然后得到p指向的元素中的num成员值(即10102)
//(p++)-> 先求得->num的值(即10101),然后再使p自加1,指向stu[1]

运行结果:

No.    Name                sex  age
10101 li lin                M   18
10102 zhang fang            M   19
10104 wang min              F   20

用结构体变量和结构体变量的指针作函数参数

将一个结构体变量的值传递给另一个函数,有三种方法:

  1. 用结构体变量的成员作参数(例如:用stu[1].num或stu[2].name作函数实参)应当注意实参和形参的类型保持一致
  2. 用结构体变量作实参。用结构体变量作实参时,采取的是值传递的方式,将结构体变量所占的内存单元的内存全部按顺序传递给形参,形参也必须是同类型的结构体变量
  3. 用指向结构体变量(或数组元素)的指针作实参,将结构体变量(或数组元素)的地址传给形参

猜你喜欢

转载自blog.csdn.net/weixin_51799303/article/details/128062932