函数的基本知识
定义函数
无返回值
void functionName(parameterList)
{
statement(s);
return; // optional
}
有返回值
typeName funtionName(parameterList)
{
statements;
return value;
}
#include <iostream>
using namespace std;
void simple();
int main()
{
// // c++ 的编程模块
cout << "main() will call the simple () function: \n";
simple(); // function
return 0;
}
void simple()
{
cout << "I'm but a simple function";
}
函数原型和函数调用
#include <iostream>
using namespace std;
void cheers(int);
double cube(double x);
int main()
{
cheers(5);
cout << "Give me a number: ";
double side;
cin >> side;
double volume = cube(side);
cout
<< "A " << side << "-foot cube has a volume of ";
cout << volume << " cubic feet. \n";
cheers(cube(2)); // 存在自动类型转换
return 0;
}
void cheers(int n)
{
using namespace std;
for (int i = 0; i < n; i++)
cout << "Cheers!";
cout << endl;
}
double cube(double x)
{
return x * x * x;
}
函数原型是一句语句,以分号结束。例如
函数原型的功能:
函数参数和按值传递
用于传递值的变量为形参(parameter),传递给函数的值为实参(argument)
多个参数用逗号隔开
#include <iostream>
using namespace std;
void n_chars(char, int);
int main()
{
int times;
char ch;
cout << "Enter a character: ";
cin >> ch;
while (ch != 'q')
{
cout << "Enter an integer: ";
cin >> times;
cout << ch;
n_chars(ch, times);
cout << "\nEnter another character or press the q-key to quit: ";
cin >> ch;
}
cout << "The value of time is " << times << ". \n";
cout << "Bye\n";
return 0;
}
void n_chars(char c, int n)
{
while (n-- > 0)
cout << c;
}
另外一个接受两个参数的的函数(抽奖概率)
#include <iostream>
long double probability(unsigned numbers, unsigned picks);
using namespace std;
int main()
{
double 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);
cout << " of winning.\n";
cout << "Next two numbers (q to quit): ";
}
cout << "Bye\n";
return 0;
}
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)
// // list 7.5
#include <iostream>
const int ArSize = 8;
int sum_arr(int arr[], int n);
// int sum_arr(const int *begin, const int *end);
using namespace std;
int main()
{
int cookies[ArSize] = {1, 2, 4, 8, 16, 32, 64, 128};
// C++ 将数组名解释为其第一个元素的地址 cookies = &cookies[0]
// 对数组名使用sizeof()将得到整个数组的长度(以字节为单位)
// int arr[] 在函数头与 int *arr 等价
cout << cookies << " = array address, ";
// int sum;
int sum = sum_arr(cookies, ArSize); // 指针减法是整数值
cout << "Total cookies eaten: " << sum << endl;
return 0;
}
int sum_arr(int arr[], int n)
{
int total = 0;
cout << arr << " = arr, ";
cout << sizeof arr << "= sizeof arr\n"; // wrong
for (int i = 0; i < n; i++)
total += arr[i];
return total;
}
函数通过指针来处理数据
其中输入arr[] 是一个指针
将数组作为参数
C++ 将数组名解释为其第一个元素的地址
函数将数组的地址赋给指针变量
nclude <iostream>
const int ArSize = 8;
int sum_arr(int arr[], int n);
// int sum_arr(const int *begin, const int *end);
using namespace std;
int main()
{
int cookies[ArSize] = {1, 2, 4, 8, 16, 32, 64, 128};
// C++ 将数组名解释为其第一个元素的地址 cookies = &cookies[0]
// 对数组名使用sizeof()将得到整个数组的长度(以字节为单位)
// int arr[] 在函数头与 int *arr 等价
cout << cookies << " = array address, ";
// int sum;
int sum = sum_arr(cookies, ArSize); // 指针减法是整数值
cout << "Total cookies eaten: " << sum << endl;
sum = sum_arr(cookies, 3);
cout << "First three eaters ate " << sum << " cookies.\n";
sum = sum_arr(cookies + 4, 4);
cout << "Last four eaters ate " << sum << " cookies.\n";
return 0;
}
int sum_arr(int arr[], int n)
{
int total = 0;
cout << arr << " = arr, ";
cout << sizeof arr << "= sizeof arr\n"; // wrong
for (int i = 0; i < n; i++)
total += arr[i];
return total;
}
填充数组
const保护数组
修改数组
结合代码
#include <iostream>
const int Max = 5;
int fill_array(double arr[], int limit);
void show_array(const double arr[], int n);
void revalue(double r, double ar[], int n);
using namespace std;
int main()
{
double properties[Max];
int size = fill_array(properties, Max);
show_array(properties, size);
cout << "Enter revaluation factor:";
double factor;
cin >> factor;
revalue(factor, properties, size);
show_array(properties, size);
cout << "Done.\n";
return 0;
}
int fill_array(double arr[], int limit)
{
double temp;
int i;
for (i = 0; i < limit; i++)
{
cout << "Enter value #" << (i + 1) << ": ";
cin >> temp;
if (!cin)
{
cin.clear();
while (cin.get() != '\n')
continue;
cout << "Bad input: input process terminated.\n";
break;
}
else if (temp < 0)
break;
arr[i] = temp;
}
return i;
}
// 展示数组
void show_array(const double arr[], int n)
{
for (int i = 0; i < n; i++)
{
cout << "Property #" << (i + 1) << " : $";
cout << arr[i] << endl;
}
}
// 修改数组
void revalue(double r, double ar[], int n)
{
for (int i = 0; i < n; i++)
ar[i] *= r;
}
使用数组区间的函数
#include <iostream>
const int ArSize = 8;
int sum_arr(const int *begin, const int *end);
using namespace std;
int main()
{
int cookies[ArSize] = {1, 2, 4, 8, 16, 32, 64, 128};
// C++ 将数组名解释为其第一个元素的地址 cookies = &cookies[0]
// 对数组名使用sizeof()将得到整个数组的长度(以字节为单位)
// int arr[] 在函数头与 int *arr 等价
cout << cookies << " = array address, ";
// int sum;
int sum = sum_arr(cookies, cookies + ArSize); // 指针减法是整数值
cout << "Total cookies eaten: " << sum << endl;
sum = sum_arr(cookies, cookies + 3);
cout << "First three eaters ate " << sum << " cookies.\n";
sum = sum_arr(cookies + 4, cookies + 8);
cout << "Last four eaters ate " << sum << " cookies.\n";
return 0;
}
int sum_arr(const int *begin, const int *end)
{
const int *pt;
int total = 0;
// cout << arr << " = arr, ";
// cout << sizeof arr << "= sizeof arr\n"; // wrong
for (pt = begin; pt != end; pt++)
total += *pt;
return total;
}
指针和const
指针指向常数对象,防止指针修改指向的值; 指针本身声明为常亮,防止指针改变指向的位置
int age = 30;
const int *pt = &age;
不能通过pt对age进行修改,但是可以通过age来修改
函数和二维数组
二维数组属于指向指针的指针
函数和C-风格字符串
表示字符串的方式
1. char数组
2. 有引号括起来的字符串常量
3. 被设置为字符串的地址的char指针
include <iostream>
int c_in_str(const char *str, char ch);
using namespace std;
int main()
{
char mmm[15] = "minimum";
char *wail = "ululate";
int ms = c_in_str(mmm, 'm');
int us = c_in_str(wail, 'u');
cout << ms << "m characters in " << mmm << endl;
cout << us << "u characters in " << wail << endl;
}
int c_in_str(const char *str, char ch)
{
int count = 0;
while (*str)
{
if (*str == ch)
count++;
str++;
}
return count;
}
返回C-风格字符串的函数
#include <iostream>
char *build(char c, int n);
using namespace std;
int main()
{
int times;
char ch;
cout << "Enter a character: ";
cin >> ch;
cout << "Enter an integer: ";
cin >> times;
char *ps = build(ch, times);
cout << ps << endl;
delete[] ps;
ps = build('+', 20);
cout << ps << "-DONE-" << ps << endl;
delete[] ps;
return 0;
}
char *build(char c, int n)
{
char *pstr = new char[n + 1];
pstr[n] = '\0';
while (n-- > 0)
pstr[n] = c;
return pstr;
}
函数和结构
传递和返回结构
#include <iostream>
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 t1);
using namespace std;
int main()
{
travel_time day1 = {5, 45};
travel_time day2 = {4, 55};
travel_time trip = sum(day1, day2);
cout << "Two-day total: ";
show_time(trip);
travel_time day3 = {4, 32};
cout << "Three-day total:";
show_time(sum(trip, day3));
return 0;
}
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 show_time(travel_time t)
{
cout << t.hours << " hours, ";
cout << t.mins << "minutes.\n";
}
另一个处理结构的函数范例
#include <iostream>
#include <cmath>
struct rect
{
double x;
double y;
};
struct polar
{
double distance;
double angle;
};
void show_polar(polar dapos);
polar rect_to_polar(rect xypos);
using namespace std;
int main()
{
rect rplace;
polar pplace;
cout << "Enter the x and the y values: ";
while (cin >> rplace.x >> rplace.y)
{
pplace = rect_to_polar(rplace);
show_polar(pplace);
cout << "Next two numbers (q to quit):";
}
cout << "Done.\n";
return 0;
}
void show_polar(polar dapos)
{
const double Rad_to_deg = 57.29577951;
cout << "distance = " << dapos.distance;
cout << ", angle = " << dapos.angle * Rad_to_deg;
cout << " degrees\n";
}
polar rect_to_polar(rect xypos)
{
polar answer;
answer.distance =
sqrt(xypos.x * xypos.x + xypos.y * xypos.y);
answer.angle = atan2(xypos.y, xypos.x);
return answer;
}
传递结构的地址
形参是指针使用间接操作符,结构使用成员操作符
间接成员操作符(->) 直接成员操作符(.)
#include <iostream>
#include <cmath>
struct rect
{
double x;
double y;
};
struct polar
{
double distance;
double angle;
};
void show_polar(const polar *pda);
void rect_to_polar(const rect *pxy, polar *pda);
using namespace std;
int main()
{
rect rplace;
polar pplace;
cout << "Enter the x and the y values: ";
while (cin >> rplace.x >> rplace.y)
{
rect_to_polar(&rplace, &pplace);
show_polar(&pplace);
cout << "Next two numbers (q to quit):";
}
cout << "Done.\n";
return 0;
}
void show_polar(const polar *pda)
{
const double Rad_to_deg = 57.29577951;
cout << "distance = " << pda->distance;
cout << ", angle = " << pda->angle * Rad_to_deg;
cout << " degrees\n";
}
void rect_to_polar(const rect *pxy, polar *pda)
{
pda->distance = sqrt(pxy->x * pxy->x + pxy->y * pxy->y);
pda->angle = atan2(pxy->y, pxy->x);
}
函数和string对象
可以用string 类型对象数组代替二维char数组;
#include <iostream>
#include <string>
using namespace std;
const int SIZE = 5;
void display(const string sa[], int n);
int main()
{
string list[SIZE];
cout << "Enter your " << SIZE << "favorite astronomical sights: \n";
for (int i = 0; i < SIZE; i++)
{
cout << i + 1 << ": ";
getline(cin, list[i]);
}
cout << "Your list: \n";
display(list, SIZE);
return 0;
}
void display(const string sa[], int n)
{
for (int i = 0; i < n; i++)
cout << i + 1 << ": " << sa[i] << endl;
}
sa 是一个指向sring对象的指针,sa[i] 是一个string对象。
递归
包含一个递归调用的递归
void recurs(argumentlist)
{
statements1;
if (test)
recurs(arguments)
statements2
}
#include <iostream>
void countdown(int n);
using namespace std;
int main()
{
countdown(4);
return 0;
}
void countdown(int n)
{
cout << "Counting down ..." << n << "(n at" << &n << ")" << endl;
if (n > 0)
countdown(n - 1);
cout << n << ": Kaboom!\n";
}
改变代码显示n的地址和值
#include <iostream>
void countdown(int n);
using namespace std;
int main()
{
countdown(4);
return 0;
}
void countdown(int n)
{
cout << "Counting down ..." << n << "(n at" << &n << ")" << endl;
if (n > 0)
countdown(n - 1);
cout << n << ": Kaboom!" << "(n at " << &n << ") " << endl;
;
}
包含多个递归调用的递归
#include <iostream>
const int Len = 66;
const int Divs = 6;
using namespace std;
void subdivide(char ar[], int low, int high, int level);
int main()
{
char ruler[Len];
int i;
for (i = 1; i < Len - 2; i++)
ruler[i] = ' ';
ruler[Len - 1] = '\0';
int max = Len - 2;
int min = 0;
ruler[min] = ruler[max] = '|';
cout << ruler << endl;
for (i = 1; i <= Divs; i++)
{
subdivide(ruler, min, max, i);
cout << ruler << endl;
for (int j = 1; j < Len - 2; j++)
ruler[j] = ' ';
}
return 0;
}
void subdivide(char ar[], int low, int high, int level)
{
if (level == 0)
return;
int mid = (high + low) / 2;
ar[mid] = '|';
subdivide(ar, low, mid, level - 1);
subdivide(ar, mid, high, level - 1);
}
函数指针
要声明指向特定类型的函数的指针,可以首先编写这种函数的原型,然后用(*pf)替换函数名,这样pf就是这类函数的指针
函数指针的基本知识
函数指针的机制
- 获取函数的地址
- 声明一个函数指针
- 使用函数指针来调用函数
获取函数地址
获取函数地址只用使用函数名,如果think()是一个函数,则think就是函数的地址
声明函数指针
要声明指向特定类型的函数的指针,可以首先编写这种函数的原型,然后用(*pf)替换函数名,这样pf就是这类函数的指针,例如
double pam (int);
double (*pf) (int);
pf = pam;
使用函数指针来调用函数
使用(*pf),将它看作函数名
函数指针示例
#include <iostream>
double betsy(int);
double pam(int);
void estimate(int lines, double (*pf)(int));
using namespace std;
int main()
{
int code;
cout << "How many lines of code do you need? ";
cin >> code;
cout << "Here's Betsy's estimate: \n";
estimate(code, betsy);
cout << "Here's Pam's estimate: \n";
estimate(code, pam);
return 0;
}
double betsy(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)\n";
}
标签:include,const,cout,int,double,c++,第七章,primer,函数
From: https://blog.csdn.net/weixin_48442204/article/details/142225727