前言
本文围绕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;
}
运行一下: