| |
|
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
| -> C++知识库 -> C++ Primer Plus 笔记(7~8章) -> 正文阅读 |
|
|
[C++知识库]C++ Primer Plus 笔记(7~8章) |
7 函数——C++的编程模块7.1复习函数的基本知识要使用C++函数,必须完成如下工作:
7.1.1 定义函数没有返回值的函数和有返回值的函数,没有返回值的函数被称为void函数 void cheers(int n)
{
? ?fot(int i = 0;i<n;i++)
? ? ? ?std::cout<<"Cheers! ";
? ?std::cout << std::endl;
}
C++对于返回值有一定的限制:不能是数组,但可以是其他任何类型——整数,浮点数,指针,甚至可以是结构和对象 7.1.2 函数原型和函数调用原型描述了函数到编译器的接口,将函数返回值的类型以及参数的类型和数量告诉编译器 另外,函数原型中的变量名只是占位符,可以与函数定义中的变量不同,甚至可以省略 void cheers(int); 7.2 函数参数和按值传递double cube(double x); 该函数将创建一个新的名为x的double变量,将其初始化为5。这样,cube()执行的操作将不会影响main()中的数据,因为cube()使用的是side的副本,不是原数据。其中,用于接收传递值的变量叫形参,传递给函数的叫实参。 7.3 函数与数组#include <iostream>
const int Arsize = 8;
int sum_arr(int arr[], int n);
int main()
{
using namespace std;
int cookies[Arsize] = { 1,2,4,8,16,32,64,128 };
int sum = sum_arr(cookies, Arsize);
cout << "Total cookies eaten: " << sum << "\n";
return 0;
}
int sum_arr(int arr[], int n)
{
int total = 0;
?
for (int i = 0; i < n; i++)
total = total + arr[i];
return total;
}
7.3.1 函数如何使用指针来处理数组C++将数组名解释为其第一个元素的地址: cookies == &cookies[0]; 该规则有一些例外。首先,数组声明使用数组名来标记存储位置;其次,对数组名使用sizeof将得到整个数组的长度(以字节为单位);最后,正如第4章指出的,将地址运算符&用于数组名时,将返回整个数组的地址,例如&cookies将返回一个32字节内存块的地址 以下有两个恒等式: arr[i] == *(arr + i); &arr[i] == arr + i; 将指针(包括数组名)加1,实际上是加上了一个与指针指向的类型长度(以字节为单位)相等的值。对于遍历数组而言,使用指针加法和数组下标是等效的 7.3.2 将数组作为参数意味着什么将数组内容传递给函数,而是将数组位置(地址),包含的元素种类(类型)以及元素数目(n变量)提交给函数 sizeof cookies是整个数组的长度,而sizeof arr只是指针变量的长度 7.3.3 更多数组函数实例
int fill_array(double ar[],int limit)
{
? ?using namespace std;
? ?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 progress terminated.\n";
? ? ? ? ? ?break;
? ? ? }
? ? ? ?else if(temp < 0)
? ? ? ? ? ?break;
? ? ? ?ar[i] = temp;
? }
? ?return i;
}
为防止函数无意中修改数组的内容,可在声明形参时使用关键字const void show array(const double ar[], int n); 7.3.4 使用数组区间的函数传统的C++方法是,将指向数组起始处的指针作为一个参数,将数组长度作为第二个参数 还有一种方法,可以通过传递两个指针来完成:一个指针标识数组的开头,另一个指针标识数组的尾部 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;
}
7.3.5 指针和const首先,声明一个指向常量的指针pt: int age = 39; const int * pt = &age; pt指向age,而age不是const。可以直接通过age变量来修改age的值,但不能使用pt指针来修改它 *pt = 20; //无效 age = 20; //有效 将指针参数声明为指向常量数据的指针有两条理由:
如果条件允许,则应将指针形参声明为指向const的指针 7.4 函数和二维数组将二维数组作为参数的函数原型有两种: int sum(int (*ar2)[4],int size); int sum(int ar2[][4],int size); 由于ar2指向数组的第一个元素,因此表达式ar2+r指向编号为r的元素,ar2[r]是编号为r的元素。 由于元素本身是一个有4个int组成的数组,因此ar2[r] [c]表示其中的一个元素 ar2; //指向(由4个int组成的)数组的第一个元素 ar2 + r; //指向编号为r的数组 *(ar2 + r); //编号为r的数组的值 *(ar2 + r) + c; //指向r数组的c元素 *((ar2 + r) + c); //r数组c元素的值 ? ar2[r][c] == *((ar2 + r) + c); 7.5 函数和C风格字符串7.5.1 将C风格字符串作为参数的函数假如要将字符串作为参数传递给函数,则表示字符串的方式有三种:
unsigned int c_in_str(const char * str,char ch)
{
? ?unsigned int count = 0;
? ?while(*str) //当*str = 0时退出循环
? {
? ? ? ?if(*str == ch)
? ? ? ? ? ?count++;
? ? ? ?str++;
? }
? ?return count;
}
7.5.2 返回c风格字符串的函数函数无法返回一个字符串,但可以返回字符串的地址 char * buildstr(char c,int n)
{
? ?char * pstr = new char[n + 1];
? ?pstr[n] = '\0';
? ?while(n-- > 0)
? ? ? ?pstr[n] = c;
? ?return pstr;
}
7.6 函数与结构7.6.1 传递和返回结构#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 t);
?
int main()
{
using namespace std;
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)
{
using namespace std;
cout << t.hours << " hours, "
<< t.mins << " minutes\n";
}
7.6.2 传递结构的地址void show_polar(const polar*pda)
{
? ?using namespace std;
? ?const double Red_to_deg = 57.29577951;
? ?
? ?cout << "distance = " << pda->distance;
? ?cout << ", angle = " << pda->angle * Red_to_deg;
? ?cout << " degrees\n";
}
需要注意三个地方:
7.7 函数和string对象void display(const string sa[],int n)
{
? ?for(int i = 0;i<n;i++)
? ? ? ?cout << i + 1 << ": " << sa[i] << endl;
}
7.8 函数和array对象void fill(std::array<double,Seasons> * pa)
{
? ?using namespace std;
? ?for(int i = 0;i < Seasons; i++)
? {
? ? ? ?cout << "Enter " << Snames[i] << " expense: ";
? ? ? ?cin >> (*pa)[i];
? }
}
7.9 递归void countdown(int n)
{
? ?using namespace std;
? ?cout << "Counting down ... " << n << endl;
? ?if(n > 0)
? ? ? ?countdown(n-1);
? ?cout << n << ": Kaboom!\n";
}
7.10 函数指针7.10.1 函数指针的基础知识
process(think); // 获取think()函数的地址 thought(think()) //获取think()函数的值
double (*pf)(int);
double pam(int); double (*pf)(int); pf = pam; //让pf指针指向pam函数 double x = pam(4); //使用函数名调用函数 double y = (*pf)(5); //使用pf指针调用pam函数 ? 7.10.2 函数指针示例#include <iostream>
double betsy(int);
double pam(int);
?
void estimate(int lines, double (*pf)(int));
?
int main()
{
using namespace std;
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 bestsy(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))
{
using namespace std;
cout << lines << " lines will take ";
cout << (*pf)(lines) << " hour(s)\n";
}
8 函数探幽8.1 c++内联函数要使用内联函数,必须采取下述措施:
通常的做法是省略原型,将整个定义(即函数头和所有函数代码)放在本应提供原型的地方 8.2 引用变量8.2.1 创建引用变量举个例子,要将rodents作为rats变量的别名,可以这样做: int rats; int & rodents = rats; 其中,&不是地址运算符,而是类型标识符的一部分。rats和rodents的值和地址相同,将rodents加1将影响这两个变量 8.2.2 将引用用作函数参数void swapr(int & a, int & b)
{
? ?int temp = a;
? ?a = b;
? ?b = temp;
}
void swapp(int * p,int * q)
{
? ?int temp = *p;
? ?*p = *q;
? ?*q = temp;
}
引用传递(别名)和地址传递(指针)都可以交换a,b的值,但值传递不能 8.2.3 将引用用于结构...
struct free_throws
{
? ?std::string name;
? ?int made;
? ?int attempts;
? ?float percents;
};
...
void display(const free_throws & ft)
{
? ?using std::cout;
? ?cout << "Name: " << ft.name << '\n';
? ?cout << " Made: " << ft.made << '\t';
? ...
}
...
8.2.4 将引用用于类对象string version1(const string & s1, const string & s2)
{
? ?string temp;
? ?temp = s2 + s1 + s2;
? ?return temp;
}
8.2.5 何时使用引用参数
8.3 函数重载8.3.1 重载示例#include <iostream>
unsigned long left(unsigned long num, unsigned ct);
char* left(const char* str, int n = 1);
?
int main()
{
using namespace std;
unsigned long n = 12312312;
int i;
char* temp;
...
for (i = 1; i < 10; i++)
{
cout << left(n, i) << endl;
temp = left(trip, i);
cout << temp << endl;
delete[] temp;
}
return 0;
}
unsigned long left(unsigned long num, unsigned ct)
{
unsigned digits = 1;
unsigned long n = num;
...
}
char* left(const char* str, int n)
{
if (n < 0)
n = 0;
...
}
8.4 函数模板需要多个对不同类型使用同一种算法的函数时,可使用模板 template<typename AnyType> //指出要建立一个模板,并将其类型命名为AnyType
void Swap(AnyType &a,AnyType &b)
{
? ?AnyType temp;
? ?temp = a;
? ?a = b;
? ?b = temp;
}
8.4.1 重载的模板#include <iostream>
template <typename T>
void Swap(T &a, T &b);
?
int main()
{
? ...
}
template <typename T>
void Swap(T &a,T &b)
{
? ?T temp;
? ?temp = a;
? ?a = b;
? ?b = temp;
}
template <typename T>
void Swap(T a[],T b[],int n)
{
? ?T temp;
? ?for(int i = 0; i < n; i++)
? {
? ? ? ?temp = a[i];
? ? ? ?a[i] = b[i];
? ? ? ?b[i] = temp;
? }
}
...
|
|
|
| C++知识库 最新文章 |
| 【C++】友元、嵌套类、异常、RTTI、类型转换 |
| 通讯录的思路与实现(C语言) |
| C++PrimerPlus 第七章 函数-C++的编程模块( |
| Problem C: 算法9-9~9-12:平衡二叉树的基本 |
| MSVC C++ UTF-8编程 |
| C++进阶 多态原理 |
| 简单string类c++实现 |
| 我的年度总结 |
| 【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
| c语言常见错误合集 |
|
|
| 上一篇文章 下一篇文章 查看所有文章 |
|
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
| 360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年11日历 | -2025/11/29 4:22:02- |
|
| 网站联系: qq:121756557 email:121756557@qq.com IT数码 |