c++学习6、函数

#include<iostream>
#include<string>
#include<array>
using namespace std;
typedef const  double* (*p_fun)(const double*, int);//利用typedef声明对函数指针创建别名————简化代码————注意该函数返回一个double指针
//其中*p_fun为其类型别名,——可以直接用其取得函数地址————p_fun p1=f1
struct travel_time//travel_time是简单类型名
{
	int hours;
	int mins;
};
struct rect
{
	double x;
	double y;
};
//要使用c++函数,要先完成三步:函数定义;提供原型;调用函数——————编译好的函数被包含在标准库头文件中
void cheers(int n);//注意原型是以分号结束!!!并不像函数创建一样
int bigger(int a, int b);//原型确保了正确处理函数返回值、参数数目是否正确、类型是否正确
int sum(int, int);//可省略函数声明时的变量名
int sum_arr(const int arr[], int n);//arr实际上并不是数组,而是一个指针
int sum_vrr(const int* begin, const int* end);
int sum_arr1(int arr1[][4]);
unsigned int c_in_str(const char* str, char ch);
char* buildstr(char c, int n);
travel_time sum_day(travel_time day1, travel_time day2);
void show_rect( const rect* pda);
void display(const string sa[], int n);//string类和函数相结合
void fill(array<string, 3>* acc);//使用类指针进行函数的值传递
void countdown(int n);
double pam(int);//函数原型中可以省略标识符
//上面几行进行了函数原型声明————原型描述了函数到编译器的接口,将函数的返回类型和参数告诉了编译器
int main()
{
	using namespace std;
	int n;
	cin >> n;
	cheers(n);//调用cheers函数
	int a, b;
	cin >> a;
	cin >> b;//这里还要再说一下cin.get()函数读取所有的输入字符,包括空格和换行符
	cout << bigger(a, b);
	cout << sum(a, b);//使用函数中的变量是一对一进行传递的,这里是实参
	//函数和数组
	int arr[10];
	for (int i = 0; i < 10; i++)
		cin >> arr[i];
	cout << sum_arr(arr, 10);//c++和c一样,将数组名视为指针当且仅当用于函数头和函数原型时————这里其实是传递数组第一个元素的地址
	//当且仅当用于函数头和函数原型时,int* arr和int arr[]才相同
	//使用数组区间的函数(range)————通过两个指针来完成——初始指针——末尾指针
	cout << sum_vrr(arr + 2, arr + 8);
	//由于数组名是地址,可对其进行加减运算,移动内存单位————arr+size-1为最后一个元素——arr+size为最后一个元素后面一个位置
	int age = 39;
	const int* pt = &age;
	//pt指向const int,因此不能使用pt来修改这个值,但可以使用age来修改,但可以修改pt的值 
	//c++禁止将const的地址赋值给非const指针!!!--非要这样做就要用强制转化
	int arr1[3][3] = { {1,2,1},{2,3,2},{3,4,5} };//对于二维数组,数组名为其地址(指针)
	cout << sum_arr1(arr1, 4);//arr1是由4个指向int的指针组成的数组!!!
	//字符串作为参数时意味着传递的是地址————是字符串的第一个字符的地址————注意字符串是以空值字符结尾(NULL符)
	char mmm[15] = "msdfmsdfma";//这里的mmm只是数组,并不是字符串
	const char* wail = "sdjfgrse";
	cout << c_in_str(mmm, 'm');//参数不一定是数组名
	cout << c_in_str(wail, 's');
	char ch;
	int num;
	cin >> ch;
	cin >> num;
	char* ps = buildstr(ch, num);//该函数返回一个字符指针
	cout << ps << endl;
	travel_time day1 = { 5,45 };
	travel_time day2 = { 4,55 };//结构体相较于数组更好和函数进行操作
	travel_time sum_day1 = sum_day(day1, day2);//可以像变量一样赋值
	cout << sum_day1.hours << sum_day1.mins << endl;
	rect rplace;
	while (cin >> rplace.x >> rplace.y)//这里还是要提一下cin的相关知识
	{//cin是istream类的一个对象。抽取运算符>>被设计使得cin>>rplace.x也是一个istream对象,其中类运算符是使用函数实现的
		cout << rplace.x << " " << rplace.y << endl;
	}
	const string s = "sdfasdfdfsa";//可以将一个对象赋值给另一个对象,可将对象作为一个完整的实体进行传递
	display(s, s.size());//注意类方法要加括号
	//这里要说的实是将对象按值将对象传递给函数,这种请况下只是一个副本,只有使用指针时才可修改原始对象
	array<string, 3>acc = { "sdfas","sdfsfwee","ijlkjon" };//模板array不仅能存储基本数据结构,还可存储类对象————对象包含对象
	for (int i = 0; i < 3; i++)
		cout << acc[i];
	//函数可以自己调用自己——递归————c++不允许mian()调用自己
	//代码中要包含终止调用链的内容————通常放在if语句中

	double(*pf)(int);//声明了一个函数指针,指向一个函数————函数名即为函数的地址
	//函数指针必须指定返回类型以及参数列表————注意要加括号————不加就是返回double类型的指针!
	//其中(*pf)就相当于原来函数,可以直接调用
	pf = pam;//pf指向函数pam
	cout << (*pf)(5);
	cout << pf(5);
	//以上两种输出其实是相同的————因为存在着历史与逻辑和看法不同
}
void cheers(int n)//———没有返回值
{//这里int n是传递的一个形参,可以使用
	using namespace std;
	for (int i = 0; i < n; i++)
	{
		cout << "cheers";//该函数没有返回值,只是进行显示
		cout << endl;
	}
}
int bigger(int a, int b)//这里有两个形参————函数返回int型
{
	using namespace std;
	if (a > b)
		return a;//有返回值的函数必须使用返回语句return
	else
		return b;
}
int sum(int a, int b)//这里传过来的是形参————但对应的变量值是相同的
{
	using namespace std;
	int c = 520;//在函数内声明的变量称为(局部变量)!!!
	cout << c;
	return a + b;
}
int sum_arr(const int arr[], int n)//为防止函数无意间修改数组的内容使用const修饰符
{
	int total = 0;
	for (int i = 0; i < n; i++)
		total = total + arr[i];//这里可以使用复合赋值运算符total+=arr[i]
	return total;
}
int sum_vrr(const int* begin, const int* end)
{
	const int* pt;
	int total = 0;
	for (pt = begin; pt != end; pt++)//这里巧妙的利用for循环和指针加1的特性达到区间遍历数组
		total += *pt;
	return total;
}
int sum_arr1(int arr1[][3], int size)//这里的size传递的是数组的行数,列数是3
{
	int total = 0;
	for (int i = 0; i < size; i++)
	{
		for (int j = 0; j < 4; j++)
			total += arr1[i][j];//这里也可以使用双重解引用:total+=*(*(arr+i)+j)
	}//注意解引用运算符的有衔接比算术高
	return total;
}
unsigned int c_in_str(const char* str, char ch)
{
	unsigned int count = 0;
	while (*str)
	{
		if (*str == ch)
			count++;
		str++;
	}
	return count;
}
char* buildstr(char c, int n)
{
	char* pstr = new char[n + 1];//使用new创建一个动态字符数组
	pstr[n] = '\0';//注意字符串以空字符结尾
	while (n--)
	{
		pstr[n] = c;
	}
	return pstr;
}
travel_time sum_day(travel_time day1, travel_time day2)//返回结构
{
	travel_time sum_day;
	sum_day.hours = day1.hours + day2.hours+(day1.mins+day2.mins)/60;
	sum_day.mins = (day1.mins + day2.mins) % 60;//利用句号来访问操作
	return sum_day;
}
void show_rect(const rect* pda)//这里传递的形参是一结构指针,并且使用了const,不允许修改原结构
{
	using namespace std;
	cout << pda->x;
	cout << pda->y;
}
void display(const string sa, int n)
{
	for (int i = 0; i < n; i++)
		cout << i + 1 << ": " << sa[i] << endl;
}
void fill(array<string, 3>* acc)
{
	using namespace std;
	for (int i; i < 3; i++)
	{
		cin >> (*acc)[i];//注意要先解引用为原本的array对象本体,再用下标运算修改各个string类
	}
}
void countdown(int n)
{
	using namespace std;//利用栈的思想可以很好的梳理递归
	cout << n << endl;//多条件递归时,更能体现————二叉数的遍历!!!书197页
	if (n > 0)//递归条件
		countdown(n - 1);
	cout << n << endl;//执行晚递归后程序将沿着进入的路径返回————像!栈!一样:先进后出
}
double pam(int a)
{
	return a * 0.02 * 0.03 * 0.24;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值