| |
|
开发:
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图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 13:41:32- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |