(九十六)函数和结构

来源:互联网 发布:点云数据 编辑:程序博客网 时间:2024/06/17 06:40

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

注:例如 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,将返回值赋值给变量ccout << 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和5return ab(def);//返回def,格式为 定义结构(使用该结构的变量名),或 直接输入def,省略ab和括号也可以}

输出:


35002FF7C0请按任意键继续. . .

总结:

①函数头:

格式为:定义的结构(如代码中的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_1getline(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~99cout << "你的体格为:" << 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 0
原创粉丝点击