C语言学习(十六)结构

在程序中需要表达数据就需要有一个变量,也会对应一种类型,我们之前所学的基础类型有int、char、double等。但是如果我们所需要表达的不是一个值,我们又希望可以用一个整体来表达,那么我们就需要用到结构。一个结构就是一种特殊的数据类型,里面可以由很多的成员,也就是用一个变量来表达多个数据。

1.结构类型

① 结构声明

形式1:
struct point //声明结构
{
int x;
int y;
};
struct point p1,p2; //定义变量

形式2:
struct point //声明结构
{
int x;
int y;
} p1,p2; //定义变量

在声明结构类型的时候,我们可以将声明放到函数里面或者函数外面。如果结构声明在函数内部,则该结构只能在函数内部使用;如果结构声明在函数外面,则结构可以被多个函数使用。

例1:声明结构类型:

#include<stdio.h>

struct date    //结构类型声明
{
	int month;
	int day;
	int year;
};

int main(int argc,char const *argv[])
{
	struct date today;  //定义一个变量today

	today.month =02;
	today.day=20;
	today.year=2019;

	printf("taday's date is %i-%i-%i.\n",today.month ,today.day,today.year);

	return 0;
}

②结构的初始化

struct date today={02,20,2019};

像数组一样,按顺序对结构中的量进行赋值。

struct date today ={.month=02,.year=2019};

这种方式可以对部分量进行赋值,此时没有对day进行赋值,那么它会对其赋初值0,这里的初始化可以类似数组初始化理解。

③结构成员
结构可以与数组类比,数组有不同单元,结构则是成员。不同的是,数组单元必须是相同类型,而结构成员可以是不同类型。

对于数组成员的写法,用“.”来进行访问,如:
today.day 与p1.x

④结构运算
要访问整个结构,直接用结构变量的名字。对于整个结构,可以进行赋值、取地址,也可以传递给函数参数。

p1=(struct point){5,10}; //相当于 p1.x=5 p1.y=10,强制类型转化为结构
p1=p2; //相当于 p1.x=p2.x p1.y=p2.y

这样的运算是数组不能实现的。

2. 结构与函数

①结构作为函数参数

整个结构可以作为参数的值传入函数,相当于在函数内新建了一个结构变量,并复制调用者的结构的值,也可以返回一个结构,这里和数组也是不一样的。

例2:结构与函数

#include<stdio.h>

struct date    //结构声明
 {
	int month;
	int day;
	int year;
};

bool isLeap(struct date d);    //函数声明
int numberOfDays(struct date d);

int main(int argc,char const *argv[])
{
	struct date today,tomorrow;

	printf("Enter today's date(mm dd yyyy):");
	scanf("%i %i %i",&today.month,&today.day,&today.year);

	if(today.day !=numberOfDays(today)) //如果今天不是这个月最后一天,只需要日都加一
	{
		tomorrow.month=today.month;
		tomorrow.year=today.year;
		tomorrow.day=today.day+1;
	}
	else if(today.month ==12)  //如果是12月且不是最后一天,也就是一年的最后一天
	{
		tomorrow.month=1;
		tomorrow.year=today.year+1;
		tomorrow.day=1;
	}
	else  //如果一个月最后一天且不是12月份
	{
		tomorrow.month=today.month+1;
		tomorrow.year=today.year;
		tomorrow.day=1;
	}

	printf("tomorrow's date is %i-%i-%i.\n",tomorrow.month ,tomorrow.day,tomorrow.year);
	
	return 0;
}
int numberOfDays(struct date d)   //计算每个月有几天,并填入数组
{
	int days;
	const int daysPerMonth[12]={31,28,31,30,31,30,31,31,30,31,30,31};

	if(d.month==2&&isLeap(d))  //如果是闰年
		days=29;
	else
		days=daysPerMonth[d.month-1];
	return days;
}

bool isLeap(struct date d)  //判断是否是闰年,是则返回true,不是则返回false
{
	bool leap=false;
	if((d.year%4==0&&d.year%100!=0)||d.year%400==0)
		leap=true;
	return leap;
}

这个程序需要注意,我用的是.cpp文件才运行成功的,也就是c++。运行结果为:
在这里插入图片描述

② 输入结构
没有直接的方式可以一次scanf一个结构。
scanf(“%d”,&p.x);
scanf(“%d”,&p.y);

在输入结构函数中,我们要记得C语言函数调用的时候是传值的,在之前的函数部分也提到过。所以我们如果在子函数中进行scanf,main函数调用输出的结果并不会是我们输入的值。

解决方案1:返回结构,进行结构之前的赋值
int main()
{
y=getStruct(); //根据结构之前可以进行=运算,直接将返回的结构赋值给y
}
struct point getStruct(void)
{
struct point p;
scanf(“%d”,&p.x);
scanf(“%d”,&p.y);
return p; //返回一个结构
}
解决方法2:结构指针作为参数(更常用的一种方法)
int main()
{
struct point y={0,0};
getStruct(&y); //取y的地址传入子函数
}
struct point* getStruct(struct point *p)
{
scanf(“%d”,&p->x);
scanf(“%d”,&p->y);
return p; //返回指针
}

3. 结构中的结构

①结构组数
struct date dates[100];
struct date dates[]={{4,5,1998},{2,13,2019}};

例3:结构数组

struct time   {
	int hour;
	int minute;
	int seconds;
};

int main(void)
{
	struct time testTimes[]={{11,59,56},{23,45,37},{8,9,23},{5,7,24}};//结构数组初始化
	int i=1;
	printf("Time is %.2i:%.2i:%.2i\n",testTimes[i].hour,testTimes[i].minute,testTimes[i].seconds);
	//结构数组值的输出
	return 0;
}

运行结果:
在这里插入图片描述

② 嵌套的结构
struct point{
int x;
int y;
};
struct rectangle{
struct point pt1;
struct point py2;
};
struct rectangle r;

就可以有:
r.pt1.x r.pt1.y
r.pt2.x r.pt2.y

猜你喜欢

转载自blog.csdn.net/qq_33523925/article/details/87649309