【C++的取经之路】(六)结构体函数与交换函数的实现

前言

本文围绕C++的函数展开介绍。参考《C++ Primer Plus》,本篇文章代码均已测试通过。


一、新建头文件和修改源文件

同样的步骤,先按模版新建Day04.h头文件,定义int Day_04(...) {}函数,后在BasicFunc.h文件中导入,再在main.cpp的程序入口函数main()函数中调用该函数。如下:

在这里插入图片描述

在这里插入图片描述


二、C++的函数

废话不多说,直接上代码。

  • 随机抽取的概率计算
long double probability(unsigned numbers, unsigned picks)
{
	/*随机抽取概率公式*/
	long double result = 1.0;
	long double n;
	unsigned p;
	for (n = numbers, p = picks; p > 0; n--, p--)
		result = result * n / p;

	return result;
}

void countProbability(int isCountProbability)
{
	/*纸牌游戏计算中奖概率:从10个数中随机抽取2个数,中奖概率为【10*9/2*1】*/
	cout << "=======Count Probability=======" << endl;

	// 交互选项
	unsigned int total, choices;
	cout << "Enter the total number of choices on the game card and\n"
		<< "the number of picks allowed:\n";
	while ((cin >> total >> choices) && choices <= total)
	{
		cout << "You have one chance in ";
		cout << probability(total, choices) << " of winning.\n";
		cout << "Next two numbers (q to quit): \n";
	}
	cout << "Bye\n";
}

  • 数组函数
int sum_arr(int arr[], int n)
{
	/*计算数组元素的和*/
	int total = 0;
	cout << arr << " = arr, "
		<< sizeof arr << " = sizeof arr\n";		//	指针变量的长度,即int类型
	for (int i = 0; i < n; i++)
		total = total + arr[i];
	return total;
}

int sum_arrp(const int* begin, const int* end)
{
	/*头尾指针方法表示*/
	const int* pt;
	int total = 0;
	for (pt = begin; pt != end; pt++)
		total = total + *pt;
	return total;
}

void  countArr(int isCountArr)
{
	/*数组函数,传入的形参值是数组名,可解释为第一个元素的内存地址*/
	cout << "=======Sum of Array=======" << endl;

	const int ArSize = 8;
	int cookies[ArSize] = { 1, 2, 4, 8, 16, 32, 64, 128 };
	cout << cookies << " = array address, "
		<< sizeof cookies << " = sizeof cookies\n";		// 整个数组的长度

	int sum = sum_arr(cookies, ArSize);
	cout << "The sum of cookies: " << sum << endl;
	sum = sum_arr(cookies, 3);
	cout << "First three sum: " << sum << endl;
	sum = sum_arr(cookies + 4, 4);		// 也即 &cookies[4],STL方法 cookies+8 即尾指针
	cout << "Last four sum: " << sum << endl;
}

  • 结构体函数,计算某时某分
struct travel_time
{
	int hours;
	int mins;
};

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 showTime(int isCountTime)
{
	/*用某时某分表示所用时间*/
	cout << "=======Show Time=======" << endl;

	travel_time day1 = { 5, 45 };
	travel_time day2 = { 4, 55 };

	travel_time trip = sum(day1, day2);
	cout << "Two-day total: ";
	cout << trip.hours << " hours, " << trip.mins << " minutes\n";

	travel_time day3 = { 4, 32 };
	cout << "Three-day total: ";
	travel_time trips = sum(trip, day3);
	cout << trips.hours << " hours, " << trips.mins << " minutes\n";
}

  • array对象
const int Seasons = 4;
// 定义array对象
const std::array<std::string, Seasons> Sname = { "Spring", "Summer", "Fall", "Winter" };

void fill(std::array<double, Seasons>* pa)
{
	/*填写季度消费金额,使用array对象*/
	for (int i = 0; i < Seasons; i++)
	{
		cout << "Enter " << Sname[i] << " expanses: ";
		cin >> (*pa)[i];
	}
}

void show(std::array<double, Seasons> da)
{
	/*输出季度消费金额,使用array对象*/
	double total = 0.0;
	cout << "EXPENSES\n";
	for (int i = 0; i < Seasons; i++)
	{
		cout << Sname[i] << ": $" << da[i] << endl;
		total += da[i];
	}
	cout << "Total Expenses: $" << total << endl;
}

void calcExpenses(int isCalcExpenses)
{
	/*array对象,计算季度消费*/
	cout << "=======Calc Season Expenses=======" << endl;

	std::array<double, Seasons> expenses;
	fill(&expenses);
	show(expenses);
}

  • 使用引用、指针、值传递三种方法实现交换函数
void swapr(int& a, int& b)
{
	/*使用引用的方法实现交换函数,&运算符意味着初始化的新变量引用原变量,与其共享同样内存地址*/
	int temp;

	temp = a;
	a = b;
	b = temp;
}

void swapp(int* p, int* q)
{
	/*使用指针传值的方法实现交换函数*/
	int temp;

	temp = *p;
	*p = *q;
	*q = temp;
}

void swapv(int a, int b)
{
	/*使用值传递的方法实现交换函数,相当于a和b复制了传入的值,并未改变原先值*/
	int temp;

	temp = a;
	a = b;
	b = temp;
}

void swap(int isSwap)
{
	/*使用三种不同的方法实现交换函数:引用、指针、值传递*/
	cout << "=======Swap=======" << endl;

	int value1 = 300, value2 = 350;
	cout << "value1 = " << value1 << ", value2 = " << value2 << endl;

	cout << "Using references to swap contents: \n";
	swapr(value1, value2);		// 引用,共享同样内存地址
	cout << "value1 = " << value1 << ", value2 = " << value2 << endl;

	cout << "Using pointers to swap contents: \n";
	swapp(&value1, &value2);		// 指针进行值传递
	cout << "value1 = " << value1 << ", value2 = " << value2 << endl;

	cout << "Using passing to swap contents: \n";
	swapv(value1, value2);		// 直接传值
	cout << "value1 = " << value1 << ", value2 = " << value2 << endl;
}

  • 结构体函数的引用
struct free_throws
{
	string name;
	int made;
	int attempts;
	float percent;
};

void set_pc(free_throws& ft)
{
	/*通过值传递的方式初始化结构体成员变量*/
	if (ft.attempts != 0)
		ft.percent = 100.0f * float(ft.made) / float(ft.attempts);
	else
		ft.percent = 0;
}

void display(const free_throws& ft)
{
	/*展示引用结构体的成员变量,使用引用作为参数传递:速度更快、使用内存更少*/
	cout << "Name: " << ft.name << '\n';
	cout << " Made: " << ft.made << '\t';
	cout << "Attempt: " << ft.made << '\t';
	cout << "Percent: " << ft.percent << endl;
}

free_throws& accumulate(free_throws& target, const free_throws& source)
{
	/*将第二个结构体成员变量累加到第一个结构体成员上,使用引用函数,使返回值同步修改*/
	target.attempts += source.attempts;
	target.made += source.made;
	set_pc(target);
	return target;
}

void strref(int isStrRef)
{
	/*结构体函数的引用、结构体成员变量的初始化*/
	cout << "=======Strref=======" << endl;

	// 初始化结构体成员
	free_throws one = { "Alex", 13, 14 };
	free_throws two = { "Bob", 10, 16 };
	free_throws three = { "Clara", 7, 9 };
	free_throws four = { "Davie", 5, 9 };
	free_throws five = { "Minne Max", 6, 14 };
	free_throws six = { "Andor Knott", 0, 0 };
	// 未初始化
	free_throws dup;

	set_pc(one);
	display(one);
	accumulate(six, one);
	// 使用返回值作为参数进行值传递
	display(accumulate(six, two));
	accumulate(accumulate(six, three), four);
	display(six);
	// 将函数返回值复制未初始化的结构体变量,注:函数返回值本身也是个引用
	dup = accumulate(six, five);
	cout << "Displaying six:\n";
	display(six);
	cout << "Displaying dup after assignment:\n";
	display(dup);
}

  • Excel中left()函数的实现
unsigned long left(unsigned long num, unsigned ct)
{
	/*返回输入字符串的前几位字符*/
	unsigned digits = 1;
	unsigned long n = num;

	if (ct == 0 || num == 0)
		return 0;
	// 使用整除10计算字符数
	while (n /= 10)
		digits++;
	// 除一次10减少一位
	if (digits > ct)
	{
		ct = digits - ct;
		while (ct--)
			num /= 10;
		return num;
	}
	else
		return num;
}

char* left(const char* str, int n)
{
	/*函数重载,返回一个指向新字符串的指针*/
	if (n < 0)
		n = 0;
	char* p = new char[n + 1];
	int i;
	for (i = 0; i < n && str[i]; i++)
		p[i] = str[i];
	// 默认空字符为字符串结束的标志
	while (i <= n)
		p[i++] = '\0';
	return p;
}

void leftover(int isLeftOver)
{
	/*返回输入字符串的前几位字符,包含函数重载*/
	cout << "=======LeftOver=======" << endl;

	const char* trip = "Hawaii!!";
	unsigned long n = 12345678;
	int i;
	char* temp;
	
	for (i = 1; i < 10; i++)
	{
		cout << left(n, i) << endl;
		temp = left(trip, i);
		cout << temp << endl;
		delete[]temp;
	}
}

Day04.h中的全部代码:

/*Day04:
	1. C++的函数
	2. 熟悉vs软件使用	
Larissa857
2/8/2025
*/


#pragma once
#include "source.h"

using namespace std;

const int Mins_per_hr = 60;
const int Seasons = 4;
// 定义array对象
const std::array<std::string, Seasons> Sname = { "Spring", "Summer", "Fall", "Winter" };

struct travel_time
{
	int hours;
	int mins;
};
// 用于结构体引用函数
struct free_throws
{
	string name;
	int made;
	int attempts;
	float percent;
};

long double probability(unsigned numbers, unsigned picks);	// 随机抽取概率公式
int sum_arr(int arr[], int n);								// 数组函数,计算数组元素之和
int sum_arrp(const int* begin, const int* end);	// STL方法表示
travel_time sum(travel_time t1, travel_time t2);	// 结构体函数,计算路程所用的时间
void fill(std::array<double, Seasons> * pa);		// 填写季度消费金额
void show(std::array<double, Seasons> da);		// 输出季度消费金额
void swapr(int& a, int& b);				// 使用引用的方法实现交换函数,适用于数据较大(如结构体和类)
void swapp(int* p, int* q);				// 使用指针的方法实现交换函数
void swapv(int a, int b);					// 尝试通过值传递交换
void display(const free_throws& ft);	// 显示引用结构体的成员变量
void set_pc(free_throws& ft);			// 值传递的方式初始化结构体成员变量
free_throws& accumulate(free_throws& target, const free_throws& source);	// 将第二个结构体成员累加到第一个成员变量
unsigned long left(unsigned long num, unsigned ct);		// 返回输入字符串的前几位字符
char* left(const char* str, int n);		// 函数重载,返回一个指向新字符串的指针

void showmenu_04(void);				// 展示功能函数模块
void countProbability(int isCountProbability);	// 随机抽取概率公式计算美国股票中奖概率
void  countArr(int isCountArr);							// 数组函数,注意形参值的传递
void showTime(int isShowTime);						// 结构体函数,用某时某分表示
void calcExpenses(int isCalcExpenses);				// array对象,输出季度消费
void swap(int isSwap);					// 使用三种方法实现交换函数:引用、指针、值传递
inline double square(double x) { return x * x; }	// 内联函数,按值传递,也可用宏定义实现
void strref(int isStrRef);				// 结构体函数的引用、结构体成员变量的初始化
void leftover(int isLeftOver);		// 返回输入字符串的前几位字符



int Day_04(...)
{
	int sign;

	cout << "Hello! Welcome to the C++ world——Day04";
	cout << endl;
	cout << "What can I help you?" << endl;
	showmenu_04();
	cin >> sign;

	switch (sign)
	{
		case 0: cout << "【Done】" << endl; break;
		case 1: countProbability(sign); break;
		case 2: countArr(sign); break;
		case 3: showTime(sign); break;
		case 4: calcExpenses(sign); break;
		case 5: swap(sign); break;
		case 6: strref(sign);	break;
		case 7: leftover(sign); break;
		case 15: cout << "Nothing to deal with :)\n"; break;
	}

	return 4;
}

void showmenu_04(void)
{
	/*展示功能函数菜单*/
	cout << "Please enter a num from 1 to 11:\n"
		"1) countProbability		2) countArr\n"
		"3) showTime					4) calcExpenses\n"
		"5) swap							6) strref\n"
		"7) leftover						8) foremore\n"
		"9) forstr							10) inputText\n"
		"11) quit\n";
}


void countProbability(int isCountProbability)
{
	/*纸牌游戏计算中奖概率:从10个数中随机抽取2个数,中奖概率为【10*9/2*1】*/
	cout << "=======Count Probability=======" << endl;

	// 交互选项
	unsigned int total, choices;
	cout << "Enter the total number of choices on the game card and\n"
		<< "the number of picks allowed:\n";
	while ((cin >> total >> choices) && choices <= total)
	{
		cout << "You have one chance in ";
		cout << probability(total, choices) << " of winning.\n";
		cout << "Next two numbers (q to quit): \n";
	}
	cout << "Bye\n";
}

void  countArr(int isCountArr)
{
	/*数组函数,传入的形参值是数组名,可解释为第一个元素的内存地址*/
	cout << "=======Sum of Array=======" << endl;

	const int ArSize = 8;
	int cookies[ArSize] = { 1, 2, 4, 8, 16, 32, 64, 128 };
	cout << cookies << " = array address, "
		<< sizeof cookies << " = sizeof cookies\n";		// 整个数组的长度

	int sum = sum_arr(cookies, ArSize);
	cout << "The sum of cookies: " << sum << endl;
	sum = sum_arr(cookies, 3);
	cout << "First three sum: " << sum << endl;
	sum = sum_arr(cookies + 4, 4);		// 也即 &cookies[4],STL方法 cookies+8 即尾指针
	cout << "Last four sum: " << sum << endl;
}

void showTime(int isCountTime)
{
	/*用某时某分表示所用时间*/
	cout << "=======Show Time=======" << endl;

	travel_time day1 = { 5, 45 };
	travel_time day2 = { 4, 55 };

	travel_time trip = sum(day1, day2);
	cout << "Two-day total: ";
	cout << trip.hours << " hours, " << trip.mins << " minutes\n";

	travel_time day3 = { 4, 32 };
	cout << "Three-day total: ";
	travel_time trips = sum(trip, day3);
	cout << trips.hours << " hours, " << trips.mins << " minutes\n";
}

void calcExpenses(int isCalcExpenses)
{
	/*array对象,计算季度消费*/
	cout << "=======Calc Season Expenses=======" << endl;

	std::array<double, Seasons> expenses;
	fill(&expenses);
	show(expenses);
}

void swap(int isSwap)
{
	/*使用三种不同的方法实现交换函数:引用、指针、值传递*/
	cout << "=======Swap=======" << endl;

	int value1 = 300, value2 = 350;
	cout << "value1 = " << value1 << ", value2 = " << value2 << endl;

	cout << "Using references to swap contents: \n";
	swapr(value1, value2);		// 引用,共享同样内存地址
	cout << "value1 = " << value1 << ", value2 = " << value2 << endl;

	cout << "Using pointers to swap contents: \n";
	swapp(&value1, &value2);		// 指针进行值传递
	cout << "value1 = " << value1 << ", value2 = " << value2 << endl;

	cout << "Using passing to swap contents: \n";
	swapv(value1, value2);		// 直接传值
	cout << "value1 = " << value1 << ", value2 = " << value2 << endl;
}

void strref(int isStrRef)
{
	/*结构体函数的引用、结构体成员变量的初始化*/
	cout << "=======Strref=======" << endl;

	// 初始化结构体成员
	free_throws one = { "Alex", 13, 14 };
	free_throws two = { "Bob", 10, 16 };
	free_throws three = { "Clara", 7, 9 };
	free_throws four = { "Davie", 5, 9 };
	free_throws five = { "Minne Max", 6, 14 };
	free_throws six = { "Andor Knott", 0, 0 };
	// 未初始化
	free_throws dup;

	set_pc(one);
	display(one);
	accumulate(six, one);
	// 使用返回值作为参数进行值传递
	display(accumulate(six, two));
	accumulate(accumulate(six, three), four);
	display(six);
	// 将函数返回值复制未初始化的结构体变量,注:函数返回值本身也是个引用
	dup = accumulate(six, five);
	cout << "Displaying six:\n";
	display(six);
	cout << "Displaying dup after assignment:\n";
	display(dup);
}

void leftover(int isLeftOver)
{
	/*返回输入字符串的前几位字符,包含函数重载*/
	cout << "=======LeftOver=======" << endl;

	const char* trip = "Hawaii!!";
	unsigned long n = 12345678;
	int i;
	char* temp;
	
	for (i = 1; i < 10; i++)
	{
		cout << left(n, i) << endl;
		temp = left(trip, i);
		cout << temp << endl;
		delete[]temp;
	}
}

// ==============基础函数==============
long double probability(unsigned numbers, unsigned picks)
{
	/*随机抽取概率公式*/
	long double result = 1.0;
	long double n;
	unsigned p;
	for (n = numbers, p = picks; p > 0; n--, p--)
		result = result * n / p;

	return result;
}

int sum_arr(int arr[], int n)
{
	/*计算数组元素的和*/
	int total = 0;
	cout << arr << " = arr, "
		<< sizeof arr << " = sizeof arr\n";		//	指针变量的长度,即int类型
	for (int i = 0; i < n; i++)
		total = total + arr[i];
	return total;
}

int sum_arrp(const int* begin, const int* end)
{
	/*头尾指针方法表示*/
	const int* pt;
	int total = 0;
	for (pt = begin; pt != end; pt++)
		total = total + *pt;
	return total;
}

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 fill(std::array<double, Seasons>* pa)
{
	/*填写季度消费金额,使用array对象*/
	for (int i = 0; i < Seasons; i++)
	{
		cout << "Enter " << Sname[i] << " expanses: ";
		cin >> (*pa)[i];
	}
}

void show(std::array<double, Seasons> da)
{
	/*输出季度消费金额,使用array对象*/
	double total = 0.0;
	cout << "EXPENSES\n";
	for (int i = 0; i < Seasons; i++)
	{
		cout << Sname[i] << ": $" << da[i] << endl;
		total += da[i];
	}
	cout << "Total Expenses: $" << total << endl;
}

void swapr(int& a, int& b)
{
	/*使用引用的方法实现交换函数,&运算符意味着初始化的新变量引用原变量,与其共享同样内存地址*/
	int temp;

	temp = a;
	a = b;
	b = temp;
}

void swapp(int* p, int* q)
{
	/*使用指针传值的方法实现交换函数*/
	int temp;

	temp = *p;
	*p = *q;
	*q = temp;
}

void swapv(int a, int b)
{
	/*使用值传递的方法实现交换函数,相当于a和b复制了传入的值,并未改变原先值*/
	int temp;

	temp = a;
	a = b;
	b = temp;
}

void display(const free_throws& ft)
{
	/*展示引用结构体的成员变量,使用引用作为参数传递:速度更快、使用内存更少*/
	cout << "Name: " << ft.name << '\n';
	cout << " Made: " << ft.made << '\t';
	cout << "Attempt: " << ft.made << '\t';
	cout << "Percent: " << ft.percent << endl;
}

void set_pc(free_throws& ft)
{
	/*通过值传递的方式初始化结构体成员变量*/
	if (ft.attempts != 0)
		ft.percent = 100.0f * float(ft.made) / float(ft.attempts);
	else
		ft.percent = 0;
}

free_throws& accumulate(free_throws& target, const free_throws& source)
{
	/*将第二个结构体成员变量累加到第一个结构体成员上,使用引用函数,使返回值同步修改*/
	target.attempts += source.attempts;
	target.made += source.made;
	set_pc(target);
	return target;
}

unsigned long left(unsigned long num, unsigned ct)
{
	/*返回输入字符串的前几位字符*/
	unsigned digits = 1;
	unsigned long n = num;

	if (ct == 0 || num == 0)
		return 0;
	// 使用整除10计算字符数
	while (n /= 10)
		digits++;
	// 除一次10减少一位
	if (digits > ct)
	{
		ct = digits - ct;
		while (ct--)
			num /= 10;
		return num;
	}
	else
		return num;
}

char* left(const char* str, int n)
{
	/*函数重载,返回一个指向新字符串的指针*/
	if (n < 0)
		n = 0;
	char* p = new char[n + 1];
	int i;
	for (i = 0; i < n && str[i]; i++)
		p[i] = str[i];
	// 默认空字符为字符串结束的标志
	while (i <= n)
		p[i++] = '\0';
	return p;
}

运行一下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Larissa857

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值