C++primer笔记
第六章
用于比较是否是字符或者数字的库函数 #include< cctype >
函数原型: int isalpha( char ch );
功能:如果参数是字母字符,函数返回非零值,否则返回零值。
函数原型: int isdigit( char ch );
功能:如果参数是字母数字,函数返回非零值,否则返回零值。
函数原型: int islower( char ch );
功能:如果参数是字母是否是小写,函数返回非零值,否则返回零值
函数原型: int isupper( char ch );
功能:如果参数是字母是否是大写,函数返回非零值,否则返回零值
switch注意事项
switch中的每一个case标签都必须是一个单独的值,这个值可以是整数或者是char类型,另外switch无法处理浮点数,case标签值必须是常量,如果选项设计取值范围、浮点测试或者两个变量的比较,则应该使用if else 语句。
6.7读取数字的循环
cin的特殊处理,cin可以强制转换成bool类型来查看当前是否有输入。
cin读取会跳过空格和换行符。cin.get()会读取所有输入的字符,包括空格和换行符。
如果输入是字符temp就为false,如果是数字,temp就是true。
int a;
bool temp = bool(cin >> a);
cin重置输入,如果输入的是字符,此时cin为false,表达式为true,进入while循环,重置输入,因此不会有任何值放入temp中。接下来用cin.get读取行尾之前的所有输入,从而删除这一行中的错误输入。
int temp;
while(!(cin>>temp)){
cin.clear();// reset input
while (cin.get() != '\n')continue;//读取回车符,不加有问题
}
6.8简单文件输入输出
必须包含fstream头文件,使用完之后必须要使用close()方法将其关闭。
警告:会用open()打开已有的文件,以接受输出时默认将他的长度截短为0,因此原来的内容将丢失。,
#include<fstream>
using namespace std;
int main() {
ofstream OutFile;
string name;
cin >> name;
OutFile.open("fish.txt");
OutFile << "make and model" << endl;
OutFile << "Now is :" <<name<< endl;
OutFile.close();
}
读取文本文件 < fstream >库
注意:方法fail()检查类型是否匹配,是就返回true但是如果遇到了EOF也返回true。一个更简单的方法是使用good(),该方法在没有发生任何错误时返回true。
#include<fstream>
using namespace std;
int main() {
ifstream inFile;
inFile.open("fish.txt");//这里 的内容为make and model回车Now is : sgfgfdgdfgg
if (!inFile.is_open()) {//判断是否成功打开
cout << "Could not open the file " << endl;
exit(EXIT_FAILURE);
}
string name;
char line[81];
inFile.getline(line, 81);//可以读取一行 值为 make and model
inFile >> name;
while (inFile.good()) {//当前输入是good并且没有遇到EOF
inFile >> name;//值为make,and,model,Now,is,: sgfgfdgdfgg
}
if(inFile.eof()){
cout<<"End of file reached.\n";
}
else if(inFile.fail()){//方法fail检查类型是否匹配,是就返回true但是如果遇到了EOF也返回true。
cout<<"Input terminated by data mismatch";
}
else {
cout<<"terminated for the unkown reason.";
}
}
第七章 函数–C++的编程模块
7.3函数和数组
下面是一个恒等式。
arr[i]==*(arr+i)
&arr[i]=arr+i
当指针指向数组时,sizeof 数组就是数组的长度,sizeof 指针就是的单个指针变量的长度
using namespace std;
int main() {
int cookies[4] = { 1,2,3,4 };
int* p = cookies;
cout << sizeof cookies << endl;
cout << sizeof p << endl;
}
16
4
使用指针指定区间计算方法。
第二个指针指向数组末尾的后一个位置
int sum_arr(const int* begin, const int* end) {
const int* pt;
int total = 0;
for (pt = begin; pt != end; pt++) {
total += *pt;
}
return total;
}
using namespace std;
int main() {
int cookies[4] = { 1,2,3,4 };
int sum = sum_arr(cookies, cookies + 4);//第二个指针指向数组末尾的后一个位置
}
7.3 指针和const
如果把g_moon的地址给pm,则可以使用pm来修改g_moon的值,这使得g_moon的const状态很荒谬,因此C++禁止将const的地址赋给非const指针。
int main() {
const float g_earth = 9.80;
const float* pe = &g_earth; //有效
const float g_moon = 1.63;
float* pm = &g_moon;//无效的
}
const 只能防止修改pt指向的值这里为39,而不能防止修改pt的值,也就是说可以将一个新地址赋给pt,如下,但是仍然不能用pt修改它的值。
int age=39;
const int *pt=&age;
int sage=80;
pt=&sage;
下面的const的使用方式,在最后一个申明中,关键词const位置与以前不同了,这种申明方式使得finger只能指向sloth,但是允许使用finger来修改slorh的值,中间申明不允许使用ps来修改sloth的值,但是允许指向另一个位置,简而言之,finger和ps都是const,而finger和ps不是。
int sloth=3;
const int *ps=&sloth;// apointer to const int
int *const finger= &sloth; //a const pointer to int
使用*运算符2次能得到值如下:
ar2[r][c]==*(*(ar2+r)+c)
7.5函数和C-风格字符串
下面的代码中char nnn里面的存储方式如下:
unsigned int c_in_str(const char* str, char ch) {
unsigned int count = 0;
while (*str) {
if (*str == ch) {
count++;
}
str++;
}
return count;
}
int main() {
char nnn[15] = "minimum";
char* str = "ululate";
unsigned int ms = c_in_str(nnn, 'm');
unsigned int us = c_in_str(str, 'u');
}
指向函数的指针:
double (*pt)(int);
dobule pam(int);
pt=pam;//pt 现在指向pam()函数
第八章 函数探幽
8.1 内联与宏
下面是一个计算平方的宏
这并不是通过传递参数实现的,而是通过文本替换来实现的–X是‘’参数‘’的符合标记
#define SQUARE(X) X*X
a=SQUARE(5.0)// is replaced by a=5.0*5.0
b=SQUARE(4.5+7.5)// is replaced by b=4.5+7.5*4.5+7.5
d=SQUARE(c++);//is replaced by d=c++*c++
上述实例可以通过括号来改进,但是对于SQUARE(C++)仍然将c递增两次如下:
#define SQUARE(X) ((X)*(X))
如下代码初始化中缺少percent则初始化为0,
#include<iostream>
#include<cstring>
using namespace std;
struct free_throws{
string name;
int made;
int attemps;
float percent;
}
void display(const free_throws &ft);
void set_pc(free_throws &ft);
free_throws &accumulate(free_throws &target, const free_throws &source);
int main(){
free_throws one={"Ifelsa Branch",13,14};
free_throws team ={"Throwgoods",0,0};
free_throws four={"Whily Looper",5,9};
accumulate(team,one);
display(accumulate(team,one));
accumulate(accumulate(team,one),four);
free_throws dup=accumulate(team.one);
accumulate(dup,one)=four;
}
void display(const free_throws ft){
cout<<ft.name<<endl;
cout<<ft.made<<endl;
cout<<ft.attempts<<endl;
cout<<ft.percent<<endl;
}
//下面为错误版本
free_throws &accumulate(free_throws *target,const free_throws &source){
target.attempts+=source.attempts;
target.made+=source.made;
return target;
}
int main(){
result=version(..,..);
}
看下面的3个版本,version1接受2个string参数并使用string类的相加功能创建新的满足要求的字符串,version4中temp是一个新的string对象,执行完之后就不存在了,因此返回指向temp的引用不可行,因此该函数的返回类型为string,这意味着temp的内容被复制到一个临时存储单元中,然后在main函数中被复制到result的string中。
string version1(const string &s1,const stirng &s2){
string temp;
temp=s1+s2+s1;
return temp;
}
const string &version2(string &s1,const string &s2){
s1=s2+s1+s2;
return s1;
}
const string &version3(string &s1,const string &s2){
string temp;
tem=s1+s2+s1;
return temp;
}
8.5函数模板
这儿的模板中的class可以换成typename,两者等价
template<class AnyType>
void swap(AnyType& a, AnyType& b) {
AnyType temp;
temp = a;
a = b;
b = temp;
}
使用方法如下:
using namespace std;
template<class AnyType>
void Swap(AnyType& a, AnyType& b);
int main() {
int a=10, b=5;
Swap(a, b);
}
template<class AnyType>
void Swap(AnyType& a, AnyType& b) {
AnyType temp;
temp = a;
a = b;
b = temp;
}
下面是非函数模板,模板函数和具体化原型,如果有多个原型,则编译器在选择原型时,非模板版本优先于具体化和模板版本,二显式具体化优先于使用模板生成的版本,下面的例题调用Swap()时使用通用模板,而第二次调用使用基于job类型的显式具体化版本 。
其中Swap< job >中的< job >是可选的,因为函数的参数类型表明,这是job的一个具体化,该原型可以这样编写:
template<> void Swap(job &,job &);
//non template function prototype
//void Swap(job &,job &);
// template protetype
template<typename,T>
void Swap(T&a,T&b);
//explicit specialization for the job type
template<>void<Swap<job>(job &a,job &b);
struct job{
char name[1];
double salary;
int floor;
}
int main(){
double u,v;
Swap(u,v)//use template
job a,b;
Swap(a,b)//use void Swap<job><job &,job &>;
}
第九章 内存模型和名称空间
名称空间
第十章 对象和类
const 成员函数
10.4 this 指针
第十二章 动态内存分配
12.4.3返回对象
12.5.3再谈定位new运算符
12.7队列模拟
第十三章 类继承
13.3.1 virtual(虚方法)
演示虚方法
13.4.1 指针和引用类型的兼容性
13.4.2 虚成员函数和动态联遍
13.4.3有关虚函数注意事项
第十四章 C++中的代码重用
14.2.1Student类示例
14.2.2 保护继承