C++ Prime Plus笔记

笔记1:结构体的初始化

结构体初始化报错:

#include <iostream>

using namespace std;

const int STRSIZE = 30;

struct bop
{
	char fullname[STRSIZE];
	char title[STRSIZE];
	char bopname[STRSIZE];
	int prefeeence;	
};
int main()
{
	//以下这么写,报错
	bop Bop[5];
	Bop[0] = {"Wimp Macho", "JJ", "1", 0};
	Bop[1] = {"Raki Rhode", "Junior Progreamer", "2", 1};
	Bop[2] = {"Celia Laiter", "MISP", "3", 1};
	Bop[3] = {"Hoppy Hipman", "Analyst Trainee", "4", 1};
	Bop[4] = {"Pat Hand", "LOOPY", "5", 1};
	return 0;
}

正确写法
书上写,必须在定义时初始化(记住)

#include <iostream>
using namespace std;

const int STRSIZE = 30;

struct bop
{
	char fullname[STRSIZE];
	char title[STRSIZE];
	char bopname[STRSIZE];
	int prefeeence;	
};
int main()
{
	bop Bop[5] = 
	{
		{"Wimp Macho", "JJ", "1", 0},
		{"Raki Rhode", "Junior Progreamer", "2", 1},
		{"Celia Laiter", "MISP", "3", 1},
		{"Hoppy Hipman", "Analyst Trainee", "4", 1},
		{"Pat Hand", "LOOPY", "5", 1}
	};
	return 0;
}

笔记2:函数指针、深入讨论函数指针

函数指针简单代码:

#include <iostream>

using namespace std;

void estimate(int line, double (*pf)(int));
double besty(int lns);
double pam(int lns);

int main()
{
	int code;
	cin >> code;
	
	estimate(code, besty);
	estimate(code, pam);
	
	return 0;
}

void estimate(int lines, double (*pf)(int))
{
	cout << lines << " lines will take " << (*pf)(lines) << " hours\n";
}

double besty(int lns)
{
	return 0.05 * lns;
}
double pam(int lns)
{
	return 0.03 * lns + 0.0004 * lns * lns;
}

函数指针笔记:

a.
利用函数指针,
相同的 函数类型及参数 可看作一类
因此,可做参数(地址传递给estimate函数,不需要重复编写estimate函数)
b.
函数指针原型:
	double (*pf)(int)
*pf与pf等价
	double pf(int)【与上述等价,建议写第一种,便于理解】
c.
double besty(int lns); 
double (*pf)(int));
double pam(int lns);
可简单看作 pf = besty, pf = pam

深入探讨函数指针:

#include <iostream>

using namespace std;

const double *f1(const double *ar, int n);
const double *f2(const double ar[], int n);
const double *f3(const double ar[], int n);

int main()
{
	double av[3] = {1112.3, 1524.6, 2227.9};
	
	//part1:
	//p1:pointer to a function
	const double *(*p1)(const double *, int) = f1;
	cout << "PART1:----------------\n";
	cout << "Address   value\n";
	cout << (*p1)(av, 3) << ": " << *(*p1)(av, 3) << endl; 
	
	//part2:
	//pa is an array of pointers
	const double *(*pa[3])(const double *, int) = {f1, f2, f3}; 
	cout << "PART2:----------------\n";
	cout << "Address   value\n";
	for(int i = 0; i < 3; i++)
		cout << pa[i](av, 3) << ": " << *pa[i](av, 3) << endl;
		
	//part3
	//pd is a pointer to an array of function pointers
	const double *(*(*pd)[3])(const double *, int) = &pa;
	cout << "PART3:----------------\n";
	cout << "Address   value\n";
	cout << (*pd)[2](av, 3) << ": " << *(*pd)[2](av, 3) << endl;
	
	return 0;
}
const double *f1(const double *ar, int n)
{
	return ar;
}
const double *f2(const double ar[], int n)
{
	return ar + 1;
}
const double *f3(const double ar[], int n)
{
	return ar + 2;
}

深入探讨函数指针笔记:

part1:
const double *(*p1)(const double *, int) = f1;
如何理解以及书写:
	f1 是函数名(地址),p1是函数指针
	a. 首先p1是一个指针
		*p1
	b.  指针是什么类型,函数类型指针
		const double * (*p1)(const double *, int ) = f1;
可简记 : p1 = f1;

part2:
const double *(*pa[3])(const double *, int) = {f1, f2, f3};
如何理解以及书写
	a. 首先pa 是一个数组,且有3个元素
		pa[3]
	b. 每个元素又是指针
		*pa[3]
	c. 每个指针又是函数指针类型
		const double * (*pa[3]) (const double *, int) = {f1, f2, f3};
可简记 pa[3] = {f1, f2, f3};

part3:
const double *(*(*pd)[3])(const double *, int) = &pa;
如何理解以及书写:
	a. 首先pd是一个地址
		*pd
	b. 这个地址有3个元素
		(*pd)[3]
	c. 这3个元素又是指针
		*(*pd)[3]
	d. 并且指针又是函数指针类型
		const double *(*(*pd)[3])(const double *, int) = &pa;
可简记: pd = &pa;
递推:  *pd = pa;
    *(*pd) = pa[0];
    
cout << (*pd)[2](av, 3) << ": " << *(*pd)[2](av, 3) << endl;
如何理解:(*pd)[2](av, 3)
pd = &pa;
(*pd) = pa;
(*pd)[2] = pa[2] = f3;

因为函数指针 *pd 与函数 pd 是等价的
即(*pd)[2](av, 3) == (*(*pd)[2])(av, 3)

如何理解: (*(*pd)[2])(av, 3)
	(*pd) == pa;
	(*pd)[2] == pa[2]
	pa[2] 相当于指向 f3 的指针,
	因为函数指针有两种写法,你可以直接用函数指针来操作,还可以用指针里面的内容来操作,
	二者是等价的。
	
	取出pa[2]里面的内容:*pa[2],即(*(*pd)[2])
	为什么不写成*(*pd)[2]
	首先:*pd == pa
	转化:
	*pa[2](av, 3) 与 (*pa[2])(av, 3)进行对比

	*pa[2](av, 3):
		pa[2] == f3
		* f3(av, 3) 表示数组第3个元素的值
	
	(*pa[2])(av, 3):
		pa[2] == f3
		*pa[2] == f3
		因为 pa[2] == *pa[2]
		f3(av, 3) 表示数组第3个元素的地址。

笔记3:无限输入字符串,遇到空白行结束

判断空白行:

1 cin
2 strcmp(str, '') == 0
	str == ''

代码1: char数组

#include <iostream>
using namespace std;
int main()
{
	char str[30];
	while(cin.get(str, 30))
	{
		cout << "^^^^^^^^^^^^^^^^^\n";
		cout << str << endl;
		cin.get();
	}
	return 0;
}

代码2:string类

#include <iostream>

using namespace std;

int main()
{
	string str;
	cout << "Please enter a line: ";
	getline(cin, str);
	while(cin)
	{
		cout << "^^^^^^^^^^\n";
		cout << str << endl;
		cout << "Please enter next line: ";
		getline(cin, str);
	}
	return 0;	
}

笔记4:

按值传递、指针、引用何时使用:
如果传递的是数组,就用指针
如果传递的是类,就用引用
如果传递的是结构体,指针和引用都可以
如果传递的是基本类型,不想修改,就用按值传递,需要修改,用指针。

笔记5:

左值引用、右值引用简单概念:

#include <iostream>

using namespace std;

int main()
{
	int a = 10; 
	int b = 20;
	
	//int &c = a;					//ture,左值引用
	//int &d = 10; 					//error,左值引用:赋值运算符左右边都要是左值 
	//int &d = a + b;				//error,同上 
	//int *p = &10					//error,不能对10取地址 
	//int *p = &(a + b);			//error,不能对a + b取地址
	//const int &d = 10;			//true,常引用,只能通过引用读数据,不能修改引用, 
	//const int &c = (a + b); 		//true,功能被限制,解决办法,C++11引用右值引用概念
	int &&x = 10;					//true,右值引用,具体功能见18章 
	int &&y = (a + b);				//true,同上
	
	
	
	return 0;
}
/*
左值、右值概念
左值:凡是能对它取地址的就是左值
右值:凡是不能对它取地址的就是右值 
*/

笔记6:

编写多个文件简单模板(使用类)

例题:
定义一个类来表示银行账户。数据成员包括储户姓名、账号(使用字符串)和存款。
成员函数执行操作如下:

创建一个对象并将其初始化;
显示储户姓名、账号和存款;
存入参数指定的存款;
取出参数指定的款项。

请编写一个简单的程序,演示以上操作

代码1:p1.h 【用来存放头文件和类声明】

#ifndef __P1_H__
#define __P1_H__

#include <iostream>

using namespace std;

class BankAccount
{
	private:
		string name;
		string accountnum;
		double balance;
	public:
		BankAccount();//初始化1(无参) 
		BankAccount(string client, string num, double bal);//初始化2(有参)
		void show() const;
		void deposit(double cash);
		void withdraw(double cash);
}

#endif

代码2:p1.cpp【用来存放函数的定义】

#include "p1.h"
/*
不用再次书写,在p1.h已经写过 
#include <iostream>
using namespace std;
*/

BankAccount::BankAccount()
{
	name = "No name";
	accountnum = "No account";
	balance = 0.0;	
}

BankAccount::BankAccount(string client, string num, double bal)
{
	name = client;
	accountnum = num;
	balance = bal;
}

void BankAccount::show() const
{
	cout << "name: " << name
	     << ", AccountNum: " << accountnum
	     << ", Balance: " << balance << endl;
}

void BankAccount::deposit(double cash)
{
	balance += cash;
}

void BankAccount::withdraw(double cash)
{
	balance -= cash;
}

代码3:main.cpp【主函数,以及操作【客户操作】】

#include "p1.h"

int main()
{
	BankAccount ba;//隐式调用默认构造函数 
	//等价于:BankAccount ba = BankAccount();//显示调用 
	
	ba.show();
	ba = BankAccount("Rick", "123456", 234.32);  //先创建临时对象,再赋值
	ba.show();
	ba.deposit(200.0);
	ba.show();
	ba.withdraw(300.0);
	ba.show(); 
	
	return 0;
}

Linux上g++运行:

g++ main.cpp p1.cpp
./a.out

结果:

Name: No name, AccountNum: No account, Balance: 0
Name: Rick, AccountNum: 123456, Balance: 234.32
Name: Rick, AccountNum: 123456, Balance: 434.32
Name: Rick, AccountNum: 123456, Balance: 134.32

小结:

构造函数与默认构造函数
情况1:无编写构造函数
	BankAccount ba;  //true,系统会自动生成默认构造函数,但该函数{空}
情况2:编写了构造函数:BankAccount(string client, string num, double bal);
	BankAccount ba; //error,没有进行类的初始化
	解决办法有2种
	1. 编写上述BankAccount();
	2. 给参数提供默认值:BankAccount(string client = "No name", string num = "No account", double bal = 0.0);
	3. 定义类的时候就使用初始化
		BankAccount ba = BankAccount("Rick", "123456", 0.0);
		BankAccount ba ("Rick", "123456", 0.0);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值