结构比字符串/数组简单之处在于,可以把一个结构赋给另一个结构,而字符串、数组不行。
注:例如 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而言,效果是一样的,只不过前者是传递一个结构指针,后者是传递了一个结构地址。