C++ - 函数

如何使用函数来处理数组、字符串和结构,并且学习赌鬼和函数指针;

函数

函数参数和按值传递

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;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值