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.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值