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