(九十六)函数和结构

结构比字符串/数组简单之处在于,可以把一个结构赋给另一个结构,而字符串、数组不行。

注:例如 struct abc{int a; int b;}这样的结构定义,其中abc为类型名。可以称之为abc结构。

 

函数可以直接返回结构,

但若需要地址的话,需要加上地址运算符&才能得到结构的地址。

 

返回结构的函数头为:

类型名 函数名(传递的参数)

如代码:

#include<iostream>
using namespace std;

struct ab	//定义ab结构
{
	int a;	//ab的两个变量
	int b;
};
ab abc(void);	//ab结构的函数原型,这个结构函数无传递参数

int main()
{
	ab c;	//声明ab结构c,c为使用ab结构的变量名。
	c = abc();	//调用结构函数abc,将返回值赋值给变量c
	cout << c.a << endl;	//打印c的变量a的值
	cout << c.b << endl;	//打印c的变量b的值
	cout << &c << endl;	//打印c的地址
	system("pause");
	return 0;
}

ab abc(void)	//ab结构的函数头,函数名为abc
{
	ab def = { 3,5 };	//初始化def,使用ab结构,赋值分别为3和5
	return ab(def);	//返回def,格式为 定义结构(使用该结构的变量名),或 直接输入def,省略ab和括号也可以
}

输出:


3
5
002FF7C0
请按任意键继续. . .

总结:

①函数头:

格式为:定义的结构(如代码中的ab) 函数名(参数);

不同的结构使用不同的定义的结构。

 

②参数:

可以无参数,也可以按实际需要传递参数。

结构名(如代码中的c)可以直接当参数进行传递,例如以上代码若要传递参数的话,改为:

ab abc(ab,ab)   注:ab是定义的结构

 

③返回值:

格式为:return 使用该结构的变量名;   或   return 定义的结构(使用该结构的变量名)

如代码中的:return def; 或  return ab(def);

二者是等价的。

结构名作为返回值的时候,返回的是这个结构所包含的所有成员变量。

 

④结构在函数中的使用方式:

像使用单体变量那样使用函数,如 函数名.变量名 这样。

只不过结构名作为参数的时候,导入的是这个结构变量的所有成员。

 

以下是以结构作为参数进行传递的代码:

#include<iostream>
#include<string>
#include<ctime>
#include<Windows.h>
using namespace std;

struct shuxing	//shuxing是类型名
{
	string name;
	int str;
};

shuxing heti(shuxing, shuxing);

int main()
{
	cout << "你和你的伙伴遇见一个强大的boss,现在你们需要合体来战胜他!" << endl;
	cout << "请输入你的姓名:";
	shuxing player_1;	//声明使用shuxing的结构player_1
	getline(cin, player_1.name);	//读取一整行,避免因为空格而导致读取的名字不完全
	cout << "系统正在测试你的体格";
	for (int i = 0;i < 5;i++)	//等待0.5*5秒
	{
		cout << ".";
		Sleep(500);
	}
	cout << endl;
	player_1.str = clock() % 100;	//随机一个属性,利用求余,范围为0~99
	cout << "你的体格为:" << player_1.str << endl;
	cout << "————————————" << endl;
	cout << "请输入你的伙伴的姓名:";
	shuxing player_2;
	getline(cin, player_2.name);
	cout << "系统正在测试你的伙伴的体格";
	for (int i = 0;i < 5;i++)
	{
		cout << ".";
		Sleep(500);
	}
	cout << endl;
	player_2.str = clock() % 100;
	cout << "你的伙伴的体格为:" << player_2.str << endl;
	cout << "现在你们俩进行合体ing";
	for (int i = 0;i < 5;i++)
	{
		cout << ".";
		Sleep(500);
	}
	shuxing bigger = heti(player_1, player_2);	//结构bigger为函数调用2个参数后的返回值
	cout << "你们已经合体完毕!\n合体后的名字为:" << bigger.name << endl;
	cout << "合体后的体格为:" << bigger.str << endl;
	cout << "请点击任意键与boss战斗" << endl;
	cin.sync();	//清除输入缓存
	cin.get();	//从而利用读取任意输入来达成等待的目的
	cout << "战斗完毕,你们胜利了!\n游戏结束" << endl;
	system("pause");
	return 0;
}

shuxing heti(shuxing player_1, shuxing player_2)
{
	shuxing sum;	//声明结构sum,计划为两个结构的之和
	sum.str = player_1.str + player_2.str;
	sum.name = player_1.name + "*" + player_2.name;
	return sum;
}

输出:


你和你的伙伴遇见一个强大的boss,现在你们需要合体来战胜他!
请输入你的姓名:wd
系统正在测试你的体格.....
你的体格为:43
————————————
请输入你的伙伴的姓名:dw
系统正在测试你的伙伴的体格.....
你的伙伴的体格为:8
现在你们俩进行合体ing.....你们已经合体完毕!
合体后的名字为:wd*dw
合体后的体格为:51
请点击任意键与boss战斗

战斗完毕,你们胜利了!
游戏结束
请按任意键继续. . .

总结:

string类型可以直接相加;

 

②可以把返回结构的函数,直接赋值给一个已被初始化的结构——因为结构可以赋给另外一个结构(只要他们使用同一个定义的结构);

如把:shuxing bigger = heti(player_1, player_2);

改成:player_1 = heti(player_1, player_2);

 

 

坐标、角度、弧度之间互相转换的代码:

#include<iostream>
#include<cmath>	//数学库,sqrt()是开方,atan2(y,x)可以求坐标x,y和原地之间的弧度值。
#include<Windows.h>

using namespace std;
struct rect	//坐标的结构,使用横坐标x和纵坐标y
{
	double x;
	double y;
};

struct jiaodu
{
	double distance;
	double jiao;
};

struct polar //使用弧度的结构,内容分别为弧度、点距离原点的距离
{
	double distance;	//距离
	double angle;	//弧度
};

rect polar_to_rect(polar);	//弧度转坐标
rect jiaodu_to_rect(jiaodu);	//角度转坐标
polar jiao_to_polar(jiaodu m);	//角度转弧度
jiaodu rect_to_jiaodu(rect);	//坐标转角度

int main()
{
	cout << "这里可以在坐标、角度、弧度之间任意转换和输出转换后的结果。" << endl;
	cout << "请输入你要输入的内容:\n1.坐标\n2.角度和距离\n3.弧度和距离。" << endl;
	char choice;
	cin >> choice;
	rect x_y;	//结构,坐标相关
	polar d_a;	//结构,弧度相关
	jiaodu d_j;	//结构,角度相关
	while (choice!='1'&&choice!='2'&&choice!='3')
	{
		cout << "输入错误,请重新输入:";
		cin.sync();
		cin >> choice;
	}
	switch (choice)
	{
	case'1':cout << "请输入x坐标:";
		cin >> x_y.x;
		cout << "请输入y坐标:";
		cin >> x_y.y;	//获得坐标
		break;
	case'2':cout << "请输入角度(单位:°):";
		cin >> d_j.jiao;
		cout << "请输入距离:";
		cin >> d_j.distance;
		x_y = jiaodu_to_rect(d_j);	//将输入的内容转为坐标
		break;
	case'3':cout << "请输入弧度(单位:rad):";
		cin >> d_a.angle;
		cout << "请输入距离:";
		cin >> d_a.distance;
		x_y = polar_to_rect(d_a);	//将输入的内容转为坐标
		break;
	}
	cout << "计算ing";
	d_j = rect_to_jiaodu(x_y);	//调用函数,将坐标转为角度
	d_a = jiao_to_polar(d_j);	//将角度转为弧度
	for (int i = 0;i < 5;i++)
	{
		cout << ".";
		Sleep(200);
	}
	cin.sync();	//清除输入缓存
	cout << "请选择你想要显示的结果:" << endl;
	cout << "1.全部\n2.x,y坐标\n3.角度和距离\n4.弧度和距离\n-->> ";
	char choice_2;
	cin >> choice_2;
	while (cin)
	{
		switch (choice_2)
		{
		case'1':
		case'2':cout << "x坐标为:" << x_y.x << "  y坐标为:" << x_y.y << endl;
			if (choice_2 != '1')break;
		case'3':cout << "距离为:" << d_j.distance << "  角度为:" << d_j.jiao << "°" << endl;
			if (choice_2 != '1')break;
		case'4':cout << "距离为:" << d_a.distance << "  弧度为:" << d_a.angle << " rad  " << endl;
		default:if (choice_2 == '1')break;cout << "输入错误,请重新输入:";cin >> choice_2;continue;
		}
		break;	//若无意外,则离开循环
	}
	system("pause");
	return 0;
}

rect polar_to_rect(polar p)	//弧度转坐标
{
	rect dian;
	//sin角度=对边/斜边。
	dian.y = sin(p.angle)*p.distance;	//对边(y) = sin角度*斜边。
	dian.x = cos(p.angle)*p.distance;	//临边(x) = sin角度*斜边
	return dian;
}
rect jiaodu_to_rect(jiaodu p)	//角度转坐标
{
	rect dian;
	const double jiao_to_angle = 57.29577951;	//角度/弧度的值大概是这个数
	double hudu = p.jiao/jiao_to_angle;	//角度除以这个值得到弧度
	dian.y = sin(hudu)*p.distance;	//对边(y) = sin弧度*斜边。
	dian.x = cos(hudu)*p.distance;	//临边(x) = sin弧度*斜边
	return dian;
}
polar jiao_to_polar(jiaodu m)	//角度转弧度
{
	polar dian;
	dian.distance = m.distance;	//距离是一样的
	const double jiao_to_angle = 57.29577951;	//角度/弧度的值大概是这个数
	dian.angle = m.jiao / jiao_to_angle;	//角度除以这个数=弧度值
	return dian;		//返回polar结构(弧度)
}
jiaodu rect_to_jiaodu(rect m)	//坐标转角度
{
	jiaodu dian;
	const double jiao_to_angle = 57.29577951;	//角度/弧度的值大概是这个数
	dian.distance = sqrt(m.x*m.x + m.y*m.y);	//利用坐标求距离
	dian.jiao = atan2(m.y, m.x)*jiao_to_angle;	//利用坐标求角度
	return dian;	//返回jiaodu结构(角度)
}

以上函数可以自由选择输入哪个类型的数据,然后决定输出哪个类型的结果(或者输出全部结果)。

 

注意:

①计算时使用的是弧度,而不是角度;

 

②由于码代码时没有理解,所以最后两个函数并非最优化。

应该为坐标转弧度的函数优先,然后再弧度转角度。

而非是代码中的坐标转角度、在角度转弧度。


结构指针、函数:

函数也可以将 结构指针 作为参数,或者返回值。

作为参数时的格式:void 函数名(结构类型*变量名)

作为返回值时:结构类型*函数名(传递的参数)

如代码:

#include<iostream>
#include<string>
using namespace std;

struct shuxing	//结构,属性
{
	string name;
	int str;
	int def;
	int hp;
	int mp;
	int luck;
	int gold;
};
shuxing*wanjia(void);	//返回值是结构地址(指针)
void combat(shuxing*);	//导入数据为指针,无返回值

int main()
{
	shuxing *player_1=wanjia();	//让玩家输入自己的属性
	cout << "现在开始计算你的战斗力..." << endl << endl;
	combat(player_1);	//计算战斗力,并输出
	system("pause");
	return 0;
}

shuxing*wanjia(void)	//返回结构指针,无传递的参数
{
	shuxing *player = new shuxing;
	cout << "这里是战斗力计算器,请输入你的名字:";
	getline(cin, player->name);	//因为是指针,所以需要用->符号
	cout << "请输入攻击力:";
	cin >> player->str;
	cout << "请输入防御力:";
	cin >> player->def;
	cout << "请输入生命值:";
	cin >> player->hp;
	cout << "请输入魔法值:";
	cin >> player->mp;
	cout << "请输入幸运:";
	cin >> player->luck;
	cout << "请输入金钱:";
	cin >> player->gold;
	return player;
}

void combat(shuxing *player)	//参数是结构指针,无返回值
{
	int zhandouli;
	zhandouli = (player->str * 5 + player->def * 2 + player->hp * 1 + player->mp*0.8)*(player->luck / 30 + 1) + player->gold*0.001;
	cout << player->name << "的战斗力为:" << zhandouli << endl;
}

注意:

①当结构的变量通过指针使用时,需要使用运算符“->”或者是“(*指针名).结构变量名”,如player->str;

 

②当传递的参数为指针(结构地址)时,除了使用指针名之外,还可以直接使用“&结构名”作为参数,即在结构名前加上地址运算符“&”;

例如,将

shuxing *player_1=wanjia(); //注意,这里返回的是 结构指针

combat(player_1);

改为:

shuxing player_1=wanjia(); //注意,这里返回的是 结构

combat(&player_1); //结构名前加上地址运算符&

 

就第二个函数combat而言,效果是一样的,只不过前者是传递一个结构指针,后者是传递了一个结构地址。

 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值