结构变量和数组一样,都可以存储多个数据项,但在涉及到函数时,结构变量的行为更接近于基本的单值变量。也就是说,与数组不同,结构将其数据组合成单个实体或数据对象,该实体被视为一个整体。可以将一个结构赋给另外一个结构,同样,也可以按值传递结构,就像普通变量那样。在这种情况下,函数将使用原始结构的副本。另外,函数也可以返回结构,与数组名就是数组第一个元素的地址不同的是,结构名只是结构的名称,要获得结构的地址,必须使用地址运算符&。在C/cpp中,都使用符号&来表示地址运算符,cpp还是用该运算符来表示引用变量。
在使用结构编程时,最直接的方式是像处理基本类型那样来处理结构,也就是说,将结构作为参数传递,并在需要时将结构作用返回值使用。然而,按值传递结构有一个缺点,如果结构非常大,则复制结构将增加内存要求,降低系统运行的速度。处于这些原因(c最初不允许按值传递),倾向于传递结构的地址,然后使用指针来访问结构的内容。
1.传递和返回结构
当结构比较小时,按值传递结构最合理,第一个例子,计算行程时间。
// travel.cpp -- using structures with functions
#include <iostream>
struct travel_time
{
int hours;
int mins;
};
const int Mins_per_hr = 60;
travel_time sum(travel_time t1, travel_time t2);
void show_time(travel_time t);
int main()
{
using namespace std;
travel_time day1 = {5, 45}; // 5 hrs, 45 min
travel_time day2 = {4, 55}; // 4 hrs, 55 min
travel_time trip = sum(day1, day2);
cout << "Two-day total: ";
show_time(trip);
travel_time day3= {4, 32};
cout << "Three-day total: ";
show_time(sum(trip, day3));
// cin.get();
return 0;
}
travel_time sum(travel_time t1, travel_time t2)
{
travel_time total;
total.mins = (t1.mins + t2.mins) % Mins_per_hr;
total.hours = t1.hours + t2.hours +
(t1.mins + t2.mins) / Mins_per_hr;
return total;
}
void show_time(travel_time t)
{
using namespace std;
cout << t.hours << " hours, "
<< t.mins << " minutes\n";
}
其中travel_time就像是一个标准的类型名,可被用来声明变量、函数的返回类型和函数的参数类型。由于total和t1变量是travel_time结构,因此可以对它们使用句点成员运算符。由于sum()函数返回travel_time结构,因此可以将其用作show_time()函数的参数。由于在默认情况下,cpp函数按值传递参数,因此函数调用show_time(sum(trip,day3))将执行函数调用sum(trip,day3),以获得其返回值。然后,show_time()调用将sum()的返回值传递给show_time()。
2.另一个处理结构的函数示例
这个例子将定义两个结果,用于表示两种不同的描述未知的方法,然后开发一个函数,将一种格式转换为另一种格式,并显示结果。按值传递。
#include <iostream>
#include <cmath>
// structure declarations
struct polar
{
double distance; // distance from origin
double angle; // direction from origin
};
struct rect
{
double x; // horizontal distance from origin
double y; // vertical distance from origin
};
// prototypes
polar rect_to_polar(rect xypos);
void show_polar(polar dapos);
int main()
{
using namespace std;
rect rplace;
polar pplace;
cout << "Enter the x and y values: ";
while (cin >> rplace.x >> rplace.y) // slick use of cin
{
pplace = rect_to_polar(rplace);
show_polar(pplace);
cout << "Next two numbers (q to quit): ";
}
cout << "Done.\n";
return 0;
}
// convert rectangular to polar coordinates
polar rect_to_polar(rect xypos)
{
using namespace std;
polar answer;
answer.distance =
sqrt( xypos.x * xypos.x + xypos.y * xypos.y);
answer.angle = atan2(xypos.y, xypos.x);
return answer; // returns a polar structure
}
// show polar coordinates, converting angle to degrees
void show_polar (polar dapos)
{
using namespace std;
const double Rad_to_deg = 57.29577951;
cout << "distance = " << dapos.distance;
cout << ", angle = " << dapos.angle * Rad_to_deg;
cout << " degrees\n";
}
3.传递结构的地址
假设要传递结构的地址而不是整个结果以节省时间和空间,则需要重新编写前面的函数,使用指向结构的指针。
1.调用函数时,将结构的地址而不是结构本身传递。
2.将形参声明为指向polar的指针,即polar*类型,由于函数不应该修改结构,因此使用了const修饰符。
3.由于形参是指针而不是结构,因此应间接成员运算符->,而不是成员运算符(句号)。
#include <iostream>
#include <cmath>
// structure templates
struct polar
{
double distance; // distance from origin
double angle; // direction from origin
};
struct rect
{
double x; // horizontal distance from origin
double y; // vertical distance from origin
};
// prototypes
void rect_to_polar(const rect * pxy, polar * pda);
void show_polar (const polar * pda);
int main()
{
using namespace std;
rect rplace;
polar pplace;
cout << "Enter the x and y values: ";
while (cin >> rplace.x >> rplace.y)
{
rect_to_polar(&rplace, &pplace); // pass addresses
show_polar(&pplace); // pass address
cout << "Next two numbers (q to quit): ";
}
cout << "Done.\n";
return 0;
}
// show polar coordinates, converting angle to degrees
void show_polar (const polar * pda)
{
using namespace std;
const double Rad_to_deg = 57.29577951;
cout << "distance = " << pda->distance;
cout << ", angle = " << pda->angle * Rad_to_deg;
cout << " degrees\n";
}
// convert rectangular to polar coordinates
void rect_to_polar(const rect * pxy, polar * pda)
{
using namespace std;
pda->distance =
sqrt(pxy->x * pxy->x + pxy->y * pxy->y);
pda->angle = atan2(pxy->y, pxy->x);
}
由于原来的rect_to_polar函数返回一个结构,因此修改麻烦一些,为了充分利用指针的效率,应使用指针,而不是返回值。为此,需要将两个指针传递给该函数。第一个指针指向要转换的结构,第二个指针指向存储转换结果的结构。函数不返回一个新的结构,而是修改调用函数中已有的结构,因此,虽然第一个参数是const指针,第二个参数不是。