C++程序设计教程(钱能)第五章 学习笔记
前言
因为时间比较紧,所以不能将书中知识点全部罗列,但代码是必须要敲的,所以这里只记录书中程序。
1. 向量参数传递
#include<iostream>
#include<fstream>
#include<iostream>
#include<sstream>
#include<vector>
using namespace std;
typedef vector<int> VI;
typedef vector<VI> VVI;
void print(const VI&);
void input(VVI&);
bool findVec(const VVI&, VI&);
void main() {
VVI matrix;
input(matrix);
VI vec;
if (findVec(matrix, vec))
print(vec);
}
//运行结果:2 3 4 5 6 7 8 9 0 -4 5 -1
void print(const VI& v) {
for (int i = 0; i < v.size(); i++) {
cout << v[i] << " ";
}
cout << "\n";
}
void input(VVI&m) {
ifstream in("abc.txt");
int n, t;
in >> n;
m.resize(n);
for (string s; n-- &&getline(in, s); ) {
for (istringstream sin(s); sin >> t; m[m.size() - n - 1].push_back(t));
}
}
bool findVec(const VVI&matrix, VI&v) {
for (int i = 0; i < matrix.size(); i++) {
for (int j = 0; j < matrix[i].size(); j++) {
if (matrix[i][j] == -1) {
v = matrix[i];
return true;
}
}
}
return false;
}
2. 函数设计的随意性
#include<iostream>
#include<vector>
using namespace std;
void print(vector<int>& v) {
for (int i = 0; i < v.size(); i++) {
cout << v[i] << " ";
}
cout << "\n";
}
vector<int> add(vector<int>& a, vector<int>&b) {
for (int i = 0; i < a.size(); i++) {
a[i] += b[i];
}
return a;
}
void main() {
int aa[] = { 1,2,3,4,5,6,7,8 };
int bb[] = { 8,7,6,5,4,3,2,1 };
vector<int>a(aa, aa + 8), b(bb, bb + 8);
vector<int>c = add(a, b);
print(a);
print(b);
print(c);
}
/* 运行结果:
9 9 9 9 9 9 9 9(函数的副作用)
8 7 6 5 4 3 2 1
9 9 9 9 9 9 9 9
*/
为了消除副作用,给指针和引用参数加上const修饰,以限制函数体中对参数的写操作。
修改后的代码如下:
//修改add()函数如下,其他不变
vector<int> add(const vector<int>& a,const vector<int>&b) {
vector<int>c(a);
for (int i = 0; i < a.size(); i++) {
c[i] += b[i];
}
return c;
}
/* 运行结果:
1 2 3 4 5 6 7 8
8 7 6 5 4 3 2 1
9 9 9 9 9 9 9 9
*/
或者
//修改add()函数如下,其他不变
vector<int> add(const vector<int>& a,const vector<int>&b) {
vector<int>c(a.size());
for (int i = 0; i < a.size(); i++) {
c[i] =a[i]+ b[i];
}
return c;
}
//运行结果同上
显然,第一种性能更好。
3. 栈区运动的演示程序
#include<iostream>
using namespace std;
int funA(int x, int y);
void funB(int& s);
int funA(int x, int y) {
int n = 5;
funB(n);
return n;
}
void funB(int& s) {
int x = 8;
s = x;
}
void main() {
int a = 6, b = 12;
a = funA(a, b);
cout << "a = " << a << endl;
}
//运行结果:a = 8
4. 局部数据不确定
#include<iostream>
#include<fstream>
#include<sstream>
#include<vector>
using namespace std;
void f() {
int b;
cout << "b = " << b << endl;
}
void main() {
int a;
cout << "a = " << a << endl;
f();
}
//编译不通过,提示:使用了未初始化的局部变量 “a”和 “b”。
5. 指针的强行访问
#include<iostream>
using namespace std;
int a = 5;//全局变量
int b = 6;//全局变量
void main() {
int* ap = (int*)4202660;//4202660是事先知道的内存区域的直接地址
*ap = 8;
cout << a << endl;
cout << int(&b) << endl;
//指针的强行访问,最原始的方法是,知道内存区域的直接地址,
//规定一个访问的类型,就可以通过指针间访读出或改变其值了。
}
//假设已知4202660为a的地址,则程序运行结束后,a的值被修改。
6. 函数指针传递
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int bitSum(int a);
bool lessThanBitSum(int a, int b);
int bitSum(int a) {
int sum = 0;
for (int x = a; x; x /= 10) {
sum += x % 10;
}
return sum;
}
bool lessThanBitSum(int a, int b) {
return bitSum(a) < bitSum(b);
}
void main() {
int a[] = { 33,61,12,19,14,71,78,59 };
vector<int>aa(a, a + 8);
sort(aa.begin(), aa.end(),lessThanBitSum);
for (int i = 0; i < aa.size(); ++i) {
cout << aa[i] << " ";
}
cout << "\n";
}
//运行结果:12 14 33 61 71 19 59 78
7. 函数指针数组
#include<iostream>
using namespace std;
typedef void (*MenuFun) ();
void f1() {
cout << "Good!\n";
}
void f2() {
cout << "Better!\n";
}
void f3(){
cout << "Best!\n";
}
void main() {
MenuFun fun[] = { f1,f2,f3 };
for (int choice = 1; choice; ) {
cout << "1-----------display Good\n"
<< "2-----------display Better\n"
<< "3-----------display Best\n"
<< "0-----------exit\n"
<< "Enter your choice:";
cin >> choice; //如果什么也不输入,一直回车,则程序停留在cin>>choice阶段
switch (choice) {
case 1:fun[0](); break;
case 2:fun[1](); break;
case 3:fun[2](); break;
case 0:return;
default:cout << "You entered a wrong key.\n";
}
}
}
运行结果:
8. 函数指针向量
#include<iostream>
using namespace std;
typedef void (*MenuFun) ();
void f1() {
cout << "Good!\n";
}
void f2() {
cout << "Better!\n";
}
void f3(){
cout << "Best!\n";
}
void main() {
vector<MenuFun> fun(3);
fun[0] = f1;
fun[1] = f2;
fun[2] = f3;
for (int choice = 1; choice; ) {
cout << "1-----------display Good\n"
<< "2-----------display Better\n"
<< "3-----------display Best\n"
<< "0-----------exit\n"
<< "Enter your choice:";
cin >> choice; //如果什么也不输入,一直回车,则程序停留在cin>>choice阶段
if (choice > 0 && choice < 4)
fun[choice - 1]();
else if (choice == 0)
return;
else
cout << "You entered a wrong key.\n";
}
}
运行结果同上
9. 重定向输入输出
#include<iostream>
using namespace std;
void main() {
//输入两个整数a、b,输出a+b
for (int a, b; cin >> a >> b; cout<<a+b<<"\n");
}
运行1: 在cmd下编译
用命令行编译C++程序见:Windows下使用命令行编译C++程序
运行2: 从abc.txt中获得输入,abc.txt必须事先存在。
//abc.txt
8 9
9 12
12 345
运行3: 从abc.txt中获得输入,并输出到xyz.txt。xyz.txt不必事先存在。
10. 读入main参数
#include<iostream>
using namespace std;
int main(int argc,char** argv) {
for (int i = 0; i < argc; i++) {
cout << argv[i] << endl;
}
}
命令行编译结果:
11. 打开main参数为名字的文件
#include<iostream>
using namespace std;
int main(int argc,char** argv) {
if (argc != 3) {
cout << "Usage:f0511 infile outfile\n";
}
else {
ifstream in(argv[1]);
ofstream out(argv[2]);
if (in&&out)//打开和创建文件成功与否
out << in.rdbuf();//将整个输入和盘托出给输出流
}
}
命令行编译结果:
说明: 输入文件input.txt必须事先存在,输出文件output.txt不必事先存在。
12. 命令解析
#include<iostream>
using namespace std;
int main(int argc,char** argv) {
if (argc != 2) {
cout << "usage:f0512 command\n";
return 1;
}
string s(argv[1]);
istringstream sin(s);
int a, b;
char c;
sin >> a >> c >> b;
switch(c) {//解析c的值
case '-':b = -b;
case '+':cout << a + b << endl; break;
case '*':cout << a * b << endl; break;
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191129150959153.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwMjQzNDMw,size_16,color_FFFFFF,t_70)case '/':cout << a / b << endl; break;
default:cout << "Error!" << endl;
}
}
命令行编译结果:
13. 辗转相除法求最大公约数
//递归函数
long gcd1(int a, int b) {
if (a%b == 0)
return b;
return gcd1(b, a%b);
}
//非递归函数,for循环
long gcd2(int a, int b) {
for(int temp; b; ){
temp = a%b;
a = b;
b = temp;
}
return a;
}
//非递归函数,用栈消去递归
long gcd3(int a, int b) {
stack<int>x;
x.push(a);
x.push(b);
while (1) {
int y = x.top();
x.pop();
int z = x.top();
x.pop();
if (z%y == 0)
return y;
x.push(y);
x.push(z%y);
}
}
另:
int fun(int a, int b)
{//正常思路求最大公约数
int item = ((a>b) ? b : a);
for (int i = item; i >= 1; i--)
{
if (a%i == 0 && b%i == 0)
return i;
}
}
14. 函数重载
#include<iostream>
using namespace std;
int my_abs(int a) {
return (a > 0) ? a : -a;
}
double my_abs(double a) {
return (a > 0) ? a : -a;
}
int main(int argc,char** argv) {
cout << my_abs(-10) << endl;
cout << my_abs(-12.34) << endl;
}
/*运行结果:
10
12.34
*/
注意:
#include<iostream>
using namespace std;
void func(long a) {
cout << "a = " << a << endl;
}
void func(double a) {
cout << "a = " << a << endl;
}
int main(int argc,char** argv) {
//int可以转换成long型和double型
func(3);//此处编译不通过,因为不知道匹配哪一个函数
}
15. 默认参数
#include<iostream>
using namespace std;
void delay(int a = 2);//声明时有默认值
void delay(int a ) {//定义时不要加默认值,否则会报错
int sum = 0;
for (int i = 1; i <= a; i++) {
for (int j = 1; j < 3500; j++) {
for (int k = 1; k < 100000; k++) {
sum++;
}
}
}
}
int main(int argc,char** argv) {
cout << "delay 2 sec...";
delay();
cout << "ended.\n";
cout << "delay 5 sec...";
delay(5);
cout << "ended.\n";
}
/*运行结果:
delay 2 sec...ended.
delay 5 sec...ended.
*/
16. 别扭的参数默认
#include<iostream>
#include<vector>
using namespace std;
vector<int>b(10, 0);
void print(const vector<int>&a = b);
bool process(vector<int>&a);
void print(const vector<int>&a) {
if (a == vector<int>(10, 0)) {
cout << "failed.\n";
return;
}
for (int i = 0; i < a.size(); i++)
cout << a[i] << " ";
cout << endl;
}
bool process(vector<int>&a) {
int sum = 0;
for (int i = 0; i < a.size(); i++)
sum += a[i];
if (sum > 100)
return true;
else
return false;
}
int main(int argc, char** argv) {
vector<int>a(10, 5);
if (process(a))
print(a);
else
print();
}
//运行结果:failed.
17. 重载函数版本
#include<iostream>
#include<vector>
using namespace std;
vector<int>b(10, 0);
void print();
void print(const vector<int>&a);
bool process(vector<int>&a);
void print() {
cout << "failed.\n";
}
void print(const vector<int>&a) {
for (int i = 0; i < a.size(); i++)
cout << a[i] << " ";
cout << endl;
}
bool process(vector<int>&a) {
int sum = 0;
for (int i = 0; i < a.size(); i++)
sum += a[i];
if (sum > 100)
return true;
else
return false;
}
int main(int argc, char** argv) {
vector<int>a(10, 5);
if (process(a))
print(a);
else
print();
}
//运行结果:failed.