如何使用函数来处理数组、字符串和结构,并且学习赌鬼和函数指针;
函数
函数参数和按值传递
C++通常按值传递参数给函数,而后者将其赋给一个新的变量;**在函数内部声明的变量包含参数是该函数私有的。**在函数被调用时,计算机为这些变量分配内存;在函数结束后,计算机释放这些变量使用的内存;
多个参数
#include <iostream>
using namespace std;
void n_char(char, int);
int _tmain(int argc, _TCHAR* argv[])
{
int times;
char ch;
cout << "Enter a character";
cin >> ch;
while (ch != 'q')
{
cout << "Enter an integer"; //输入需要打印的字符
cin >> times;
n_char(ch, times);
cout << "Enter q Exit"; //打印多少次
cin >> ch;
}
return 0;
}
void n_char(char c, int n)
{
while (n-- > 0)
{
cout << c;
}
}
函数和数组
#include <iostream>
const double* f1(const double ar[], int n);
const double* f2(const double[], int);
const double* f3(const double*, int);
int _tmain(int argc, _TCHAR* argv[])
{
using namespace std;
double av[3] = { 1112.3, 1542.6, 2227.9 };
// pointer to a function
typedef const double *(*p_fun)(const double *, int);
p_fun p1 = f1;
auto p2 = f2; // C++0x automatic type deduction
cout << "Using pointers to functions:\n";
cout << " Address Value\n";
cout << (*p1)(av, 3) << ": " << *(*p1)(av, 3) << endl;
cout << p2(av, 3) << ": " << *p2(av, 3) << endl;
// pa an array of pointers
p_fun pa[3] = { f1, f2, f3 };
// auto doesn't work with list initialization
// but it does work for initializing to a single value
// pb a pointer to first element of pa
auto pb = pa;
cout << "\nUsing an array of pointers to functions:\n";
cout << " Address Value\n";
for (int i = 0; i < 3; i++)
cout << pa[i](av, 3) << ": " << *pa[i](av, 3) << endl;
cout << "\nUsing a pointer to a pointer to a function:\n";
cout << " Address Value\n";
for (int i = 0; i < 3; i++)
cout << pb[i](av, 3) << ": " << *pb[i](av, 3) << endl;
// what about a pointer to an array of function pointers
cout << "\nUsing pointers to an array of pointers:\n";
cout << " Address Value\n";
// easy way to declare pc
auto pc = &pa;
cout << (*pc)[0](av, 3) << ": " << *(*pc)[0](av, 3) << endl;
// slightly harder way to declare pd
p_fun(*pd)[3] = &pa;
// store return value in pdb
const double * pdb = (*pd)[1](av, 3);
cout << pdb << ": " << *pdb << endl;
// alternative notation
cout << (*(*pd)[2])(av, 3) << ": " << *(*(*pd)[2])(av, 3) << endl;
// cin.get();
return 0;
}
const double * f1(const double * ar, int n)
{
return ar;
}
const double * f2(const double ar[], int n)
{
return ar + 1;
}
const double * f3(const double ar[], int n)
{
return ar + 2;
}
指针处理函数
在大多数情况下,C++和C一样,也将数组名视为指针;
如果我们将数组作为参数,那么实际上并没有将数组内容传递给函数,而是将数组的位置、包含的元素种类以及元素数目提交给函数;
#include <iostream>
using namespace std;
const int ArSize = 8;
int sum_arr(const int* begin, const int* end);
int _tmain(int argc, _TCHAR* argv[])
{
int cookies[ArSize] = { 1, 2, 4, 8, 16, 32, 64, 128 };
int sum = sum_arr(cookies, cookies + ArSize);
cout << sum << endl;
sum = sum_arr(cookies, cookies + 3);
cout << sum << endl;
sum = sum_arr(cookies + 4, cookies + 8);
cout << sum << endl;
return 0;
}
int sum_arr(const int* begin, const int* end)
{
const int* pt;
int total = 0;
for (pt = begin; pt != end; pt++)
{
total = total + *pt;
}
return total;
}
指针和const
将const用于指针有一些很微妙的地方,可以用两种不同的方式将const关键字用于指针。第一种方法是让指针指向一个常量对象,这样可以防止使用该指针来修改指针指向的值,第二种方法是将指针本身声明为常量,这样可以防止改变指针指向的位置;
函数和二维数组
如果需要编写将二维数组作为参数的函数,必须牢记,数组名被视为其地址,因此,相应的形参是一个指针,就像一维数组一样;
#include <iostream>
using namespace std;
int sum(int(*ar2)[4], int size);
//int sum(int[][4],int size);
int _tmain(int argc, _TCHAR* argv[])
{
int data[3][4] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } };
int a[100][4];
int b[6][4];
int total1 = sum(data, 2);
int total2 = sum(data, 3);
int total3 = sum(data, 1);
int total4 = sum(data + 1, 2);
cout << total1 << endl;
cout << total2 << endl;
cout << total3 << endl;
cout << total4 << endl;
return 0;
}
int sum(int(*ar)[4], int size)
{
int total = 0;
for (int i = 0; i < size; i++)
{
for (size_t j = 0; j < 4; j++)
{
total += ar[i][j];
}
}
return total;
}
函数和结构
虽然结构变量和数组一样,都可以存储多个数据项,但在涉及到函数的时候,结构变量的行为更接近于基本的单值变量。
使用结构时,最直接的方法就是按处理基本类型那样来处理结构:也就是说,将结构作为参数传递,并在需要时将结构用作返回值使用;
传递和返回结构
当结构较小时,按值传递结构最为合理;
#include <iostream>
using namespace std;
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 _tmain(int argc, _TCHAR* argv[])
{
travel_time day1 = { 5, 45 };
travel_time day2 = { 4, 55 };
travel_time trip = sum(day1, day2);
show_time(trip);
travel_time day3 = { 4, 32 };
show_time(sum(trip,day3));
return 0;
}
travel_time sum(travel_time t1, travel_time t2) //标准结构名travel_time
{
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)
{
cout << "t.hours:" <<t.hours << "t.mins" << t.mins << endl;
}
传递结构地址
要传递结构的地址而不是整个结构以节省时间和空间,则需要重新编写前面的函数,使用指向结构的指针。
- 调用函数时,将结构的地址而不是结构本身传递给它;
- 将形参声明为指向结构本身的指针
- 由于形参是指针而不是结构,应该使用间接成员运算符(->);
#include <iostream>
#include <cmath>
using namespace std;
struct polar
{
double distance;
double angle;
};
struct rect
{
double x;
double y;
};
void rect_to_polar(const rect* pxy, polar* pda);
void show_polar(const polar* pda);
int _tmain(int argc, _TCHAR* argv[])
{
rect rplace;
polar pplace;
cout << "Enter the x and y volues:";
while (cin >> rplace.x >> rplace.y)
{
rect_to_polar(&rplace, &pplace);
show_polar(&pplace);
}
cout << "Done\n";
return 0;
}
void rect_to_polar(const rect* pxy, polar* pda)
{
pda->distance = sqrt(pxy->x * pxy->x + pxy->y + pxy->y);
pda->angle = atan2(pxy->x, pxy->y);
}
void show_polar(const polar* pda)
{
const double Rad_to_deg = 57.295123123;
cout << "distance = " << pda->distance;
cout << ", angle = " << pda->angle * Rad_to_deg;
}
函数指针
与数据项相似,函数也有地址。函数的地址是存储其机器语言代码的内存的开始地址。
函数指针基础知识
- 获取函数的地址;
- 声明一个函数指针;
- 使用函数指针来调用函数;
声明函数指针
声明指向某种类型的指针时,必须指定指针指向的类型。同样,生命之想函数的指针时,也必须指定指针指向的函数类型。这意味着声明应指定函数的返回类型以及函数的参数列表;
使用指针来调用函数
#include <iostream>
using namespace std;
double besty(int);
double pam(int);
void estimate(int lines, double(*pf)(int));
int _tmain(int argc, _TCHAR* argv[])
{
int code;
cin >> code;
estimate(code, besty);
estimate(code, pam);
return 0;
}
double besty(int lns)
{
return 0.05 * lns;
}
double pam(int lns)
{
return 0.03 * lns + 0.0004 * lns * lns;
}
void estimate(int lines, double(*pf)(int))
{
cout << lines << "lines will take";
cout << (*pf)(lines) << "hour(s)";
}
使用typedef
const double* estimate1(const double*, int); //函数声明
typedef const double* (*p_fun)(const double*, int); //使用typedef简化
p_fun p1 = estimate1;