CPP Primer初级_2
0 博客介绍
看自动驾驶代码需要,自学CPP初级基础知识。因多个文件,需要使用Python处理为markdown文本,方便博客记录。
6 函数
6.1.1_局部对象
#include <iostream>
#include <vector>
using namespace std;
/********************************************************************
6.1.1 局部对象
**********************************************************************/
int k=100; //全局对象
void do_A(int para){ //para 是局部对象
static int m=8; //m是局部对象
k=k+para;
};
size_t count_calls(){
static size_t ctr=0;
return ++ctr;
}
int main()
{
cout<<count_calls()<<endl; //输出 0
cout<<count_calls()<<endl; //输出 1
cout<<count_calls()<<endl; //输出 2
//cout<<ctr; //提示错误
}
6.1.2_myfunc
#include "myfunc.h"//
#include <iostream>
using namespace std;
// Created by Administrator on 2021/6/22/022.
//
void print1(int *arr,int size)
{
for (int i = 0; i!=size ; ++i) {
cout<<arr[i]<<" ";
}
cout<<endl;
}
6.1.2_myfunc.h
//
// Created by Administrator on 2021/6/22/022.
//
#ifndef CPP_PRIMER_MYFUNC_H
#define CPP_PRIMER_MYFUNC_H
//函数声明
void print1(int *,int );
#endif //CPP_PRIMER_MYFUNC_H
6.1.2_函数申明
#include <iostream>
#include <vector>
#include <cstdlib>
using namespace std;
#include "myfunc.h"
/********************************************************************
6.1.2 函数声明
**********************************************************************/
int sum(int a=10,int b=10)
{
return a+b;
}
int main() {
int data[] = {2, 4, 6, 8, 0, 1, 3, 5, 7, 9};
print1(data, 10); //输出 2 4 6 8 0 1 3 5 7 9
cout << sum(1, 2) << endl; //输出 3
cout << sum(1) << endl; //输出 11
cout << sum() << endl; //输出 20
return 0;
}
6.3_返回类型return
#include <iostream>
#include <vector>
#include <cstdlib>
using namespace std;
/********************************************************************
return
**********************************************************************/
void do1() //void表示没有返回值
{
cout<<"a"<<endl;
cout<<"aa"<<endl;
return ;
cout<<"aaa"<<endl;
cout<<"aah"<<endl;
// return; //可以省略
}
int& add_1(int& x) //返回引用类型
{
++x;
return x;
}
string maka_pls(size_t ctr,const string &word, const string &ending)
{
return (ctr==1)?word:word+ending;
}
const string & mp1(const string& s)
{
// string temp=s;
// return temp; //返回局部对象引用
}
int* mp2()
{
int a=100;
int *p=&a;
return p; //返回局部对象指针
}
char &get_val(string &str,string::size_type i)
{
return str[i];
}
int main()
{
cout<<"这是main()"<<endl; //输出 这是main()
do1(); //输出 a aa
cout<<"这是main end."<<endl; //输出 这是main end.
int a=10,b=20;
add_1(a);
cout<<a<<endl; // 输出 11
int& c= add_1(b); //使用引用类型接收
++c;
cout<<"b="<<b<<",c="<<c<<endl; // 输出 b=22,c=22
int cnt=6;
string animals= maka_pls(cnt,"dog","s");
cout<<cnt<<" "<<animals<< endl; //输出 6 dogs
string s("hello");
char &s_c= get_val(s,1);
s_c='i';
cout<<s<<endl; //输出 hillo
//返回值是一个左值
get_val(s,0)='k';
cout<<s<<endl; //输出 killo
return EXIT_SUCCESS;
}
6.3附_递归
#include <iostream>
#include <vector>
using namespace std;
/********************************************************************
递归
**********************************************************************/
long Mult_m(int n)
{
if (n==0)
return 1;
else
return n*Mult_m(n-1);
}
long Mult_n(int n)
{
long result=1;
for (int i = n; i > 0; --i) {
result=i*result;
}
return result;
}
int main()
{
for (int i = 0; i < 10; ++i) {
cout<<"递归"<<i<<"!="<<Mult_m(i)<<endl;
cout<<"迭代"<<i<<"!="<<Mult_n(i)<<endl;
}
return 0;
}
6.4.1_重载作用域
#include <iostream>
#include <vector>
#include <string>
using namespace std;
/********************************************************************
6.4.1 重载作用域
**********************************************************************/
void print(const string &);
void print(double );
void print(int);
void foobar(int ival)
{
// //发生函数隐藏导致屏蔽,最好使用头文件
// void print(int); //这是一个局部的函数声明,最好不要用
print("hello"); //输出 string:hello
print(ival); //输出 int:1
print(3.14); //输出 double:3.14
}
void print(int x)
{
cout<<"int:"<<x<<endl;
}
void print(double d)
{
cout<<"double:"<<d<<endl;
}
void print(const string &s)
{
cout<<"string:"<<s<<endl;
}
int main()
{
foobar(1);
return 0;
}
6.4_函数重载
#include <iostream>
#include <vector>
#include <string>
using namespace std;
typedef int int_a ;
typedef size_t int_r ;
typedef string string_n;
/********************************************************************
6.4 重载函数
**********************************************************************/
void show_int(int x)
{
cout<<x<<endl;
}
void show_vec(vector<int> v)
{
for (vector<int>::iterator iter=v.begin();iter!= v.end(); ++iter) {
cout<<*iter<<" ";
}
cout<<endl;
}
void show(int x)
{
cout<<x<<endl;
}
void show(vector<int> v)
{
for (vector<int>::iterator iter=v.begin();iter!= v.end(); ++iter) {
cout<<*iter<<" ";
}
cout<<endl;
}
class record
{
public:
int_a id ;
int_r phone ;
string_n name;
};
void lookup_id(const int_a& acct)
{
cout<<"使用账号查找"<<endl;
}
void lookup_phone(const int_r& ph)
{
cout<<"使用电话查找"<<endl;
}
void lookup_name(const string_n& na)
{
cout<<"使用姓名查找"<<endl;
}
void lookup(const int_a& acct)
{
cout<<"使用账号查找"<<endl;
}
void lookup(const int_r& ph)
{
cout<<"使用电话查找"<<endl;
}
void lookup(const string_n& na)
{
cout<<"使用姓名查找"<<endl;
}
int main()
{
int a=89;
vector<int> b;
b.push_back(1);
b.push_back(2);
b.push_back(3);
show_int(a);// 输出 89
show_vec(b); // 输出 1 2 3
//使用函数重载
show(a); // 输出 89
show(b); // 输出 1 2 3
record vip1;
vip1.id=1001;
vip1.phone=186;
vip1.name="jack";
lookup_id(1001); //acct:1001 输出 使用账号查找
lookup_phone(186); //ph:186 输出 使用电话查找
lookup_name("jack"); //na:jack 输出 使用姓名查找
lookup(1001); //acct:1001 输出 使用账号查找
lookup(186); //ph:186 输出 使用电话查找
lookup("jack"); //na:jack 输出 使用姓名查找
return 0;
}
6.5.2_内联函数
#include <iostream>
#include <vector>
#include <string>
using namespace std;
/********************************************************************
6.5.2 内联函数
**********************************************************************/
inline int sum(int a,int b)
{
return a+b;
}
inline const string &short_s(const string &s1,const string & s2)
{
return s1.size()<s2.size()?s1:s2;
}
int main()
{
int x[]={1,2,3,4,5};
int y[]={1,2,3,4,5};
for (int i = 0; i < 5; ++i) {
cout<<sum(x[i],y[i])<<endl; //优势是在编译的时候,替换为x[i]+y[i],避免中断调用
}
cout<<short_s("hello","hi")<<endl;
return 0;
}
6.6.1_实参转换
#include <iostream>
#include <vector>
#include <string>
using namespace std;
/********************************************************************
6.6.1 实参转换
**********************************************************************/
enum data
{
inline1=128,
virtual1
};
void ff(data t)
{
cout<<"ff(data t)"<<endl;
}
void f(short b)
{
cout<<"f(short b)"<<endl;
}
void f(int a)
{
cout<<"f(int a)"<<endl;
}
void f(long x)
{
cout<<"f(long x)"<<endl;
}
void f(float y)
{
cout<<"f(float)"<<endl;
}
void ff(int *p)
{
cout<<"ff(int *p)"<<endl;
}
void ff(const int *p)
{
cout<<"ff(const int *p)"<<endl;
}
int main()
{
f('a'); //int 优先级 高于short 输出 f(int a)
// f(5.66); //long和double优先级一致,存在二义性 换成float可行
data jack1=inline1;
ff(jack1); //输出 ff(data t)
ff(inline1); //输出 ff(data t)
int m=15,n=25;
int *p1=&m;
const int *p2=&n;
ff(p1); //输出 ff(int *p)
ff(p2); //输出 ff(const int *p)
return 0;
}
6.6_函数匹配
#include <iostream>
#include <vector>
#include <string>
using namespace std;
/********************************************************************
6.6 函数匹配
**********************************************************************/
void f()
{
cout<<"f()"<<endl;
}
void f(int a)
{
cout<<"f(int a)"<<endl;
}
void f(int a,int b)
{
cout<<"f(int a,int b)"<<endl;
}
void f(double a,double b=3.14)
{
cout<<"f(double a,double b)"<<endl;
}
void g(int a )
{
cout<<"f(int a)"<<endl;
}
int main()
{
f(8); //输出 f(int a)
//1.调用候选函数 2.选择可行函数 3 选择最佳匹配
f(5.66); //可行函数 f(int a),f(double a, double b=3.14) 输出 f(double a,double b)
// f(42,2.56); //有二义性,不可执行
f(static_cast<double>(42),2.56); // 输出 f(double a,double b)
return 0;
}
6.7_函数指针
#include <iostream>
#include <vector>
#include <string>
using namespace std;
/********************************************************************
6.7 函数指针
**********************************************************************/
typedef string::size_type (*comp_func)(const string& ,const string & );
bool length_s(const string& s1,const string & s2)
{
return s1.size()==s2.size();
}
string::size_type length_sum(const string& s1,const string & s2)
{
return s1.size()+s2.size();
}
void use_bigger(
const string &s1,
const string &s2,
bool (*pf)(const string& ,const string & ))
{
cout<<pf(s1,s2)<<endl;
}
int demo(int *p,int a)
{return 12;
}
// dd是一个函数,有一个形参x,返回结果是一个函数指针int(*)(int *,int)
int (*dd(int x))(int *,int)
{
cout<<x<<endl;
return demo;
}
int main()
{
int a=5;
int *ptr_a;
ptr_a=&a;
cout<<*ptr_a<<endl; //输出 5
// pf是一个指针,指向函数的指针:函数类型
bool (*pf) (const string&,const string &);
// bool (*pf2) (const string&,const string &);
// bool (*pf3) (const string&,const string &);
comp_func pf2=0;
comp_func pf3=0;
pf2=&length_sum;
use_bigger("hi","hello",length_s); //输出 0
pf=&length_s; //函数名称指向函数的指针
cout<<pf("hello","hi")<<endl; //输出 0
cout<<length_s("hello","hi")<<endl; //输出 0
cout<<dd(2)(&a,a)<<endl; //输出 2 12
}
7 类
7.1.1_类成员函数
#include <iostream>
#include <vector>
#include <string>
using namespace std;
/********************************************************************
7.1.1 类函数
**********************************************************************/
//全局函数或者外部函数
int sum1(int x, int y)
{
return x+y;
}
class sale_item{
//private:
public:
sale_item():unit_sold(0), revenue(0.0) //int double 初始化,但是string不用,会自动初始化
{
}
public:
bool same_isbn(const sale_item &aabb)
{
return isbn==aabb.isbn;
// this->return isbn==aabb.isbn; //this 代表当前对象
}
public:
string isbn; //书号
int unit_sold; //数量
double revenue; //收入
public:
double aver_price1() const;
double aver_price2() const
{
if(this->unit_sold)
return this->revenue/this->unit_sold;
else
return 0;
}
};
// 2个冒号代表范围解析,属于这个类 const卸载后面
double sale_item::aver_price1() const
{
if(this->unit_sold)
return this->revenue/this->unit_sold;
else
return 0;
}
int main()
{
sale_item item1,item2;
item1.isbn="0-201-78345-x";
item1.unit_sold=10;
item1.revenue=300.00;
item2.isbn="0-202-78345-x";
item2.unit_sold=15;
item2.revenue=360.00;
if (item1.same_isbn(item2))
cout<<"这两本书同一本书"<<endl;
else
cout<<"这两本书不是同一本书"<<endl; //输出 这两本书不是同一本书
cout<<item1.aver_price1()<<endl; //输出 24
cout<<item2.aver_price1()<<endl; //输出 30
cout<<item1.aver_price2()<<endl; //输出 30
cout<<item2.aver_price2()<<endl; //输出 24
return 0;
}
7.1.4_类构造函数
#include <iostream>
#include <vector>
#include <string>
using namespace std;
/********************************************************************
7.1.4 类构造函数
**********************************************************************/
class person
{
public:
person():money(1) //构造函数的初始化列表
{
// money=1; //构造函数的初始化列表方法2
}
public:
;
public:
int money;
};
class book{
public:
int num;
string name; //string 自动初始化 空字符串
};
book math1; // 全局类函数,int num自动初始化为0
int main()
{
// aa,bb都是对象,原来没有这个对象
person aa; //创建对象aa时,通过调用person的构造函数创建对象
person bb; //这一行就是创建对象
book chinese1; //该处int num不初始化
static book chinese2; //static同全局类函数,该处int num初始化为0
cout<<aa.money<<endl; //输出 1
cout<<"我出生时就有钱:"<<bb.money<<endl; //输出 我出生时就有钱:1
}
8 IO库
8.1.1_标准库IO
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
using namespace std;
/********************************************************************
8.1.1 标准库IO
**********************************************************************/
void print1(ofstream& ptr) //流不能复制,但是可以引用
{
cout<<"test1"<<endl;
}
ofstream& print2(ofstream& ptr) //流不能复制,但是可以引用或者指针
{
cout<<"test2"<<endl;
ofstream of2;
return of2;
}
void foo(ostream& ooss)
{
cout<<"test oosss"<<endl;
}
int main()
{
int a=5;
cout<<a<<endl; //cout 是ostream输出流对象
std::fstream fs;
std::stringstream ss;
std::ofstream out1,out2;
// out1=out2; //错的,不能赋值、复制、拷贝
print1(out1); //输出 test1
print2(out2); //输出 test2
// vector<ofstream> vec; //错误,放在容器内的对象必须可以复制
// vec.push_back(out1);
// vec.push_back(out2);
foo(cout); //输出 test oosss
ofstream offdata; //参数时基类,派生类都能传递
foo(offdata); //输出 test oosss
return 0;
}
8.1.2_条件状态
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <stdexcept>
using namespace std;
/********************************************************************
8.1.2 条件状态
**********************************************************************/
void check_cin_state(istream& st_data)
{
if (st_data.bad())
cout<<"cin bad()"<<endl;
else
cout<<"cin not bad()"<<endl;
if (st_data.fail())
cout<<"cin fail()"<<endl;
else
cout<<"cin not fail()"<<endl;
if (st_data.eof())
cout<<"cin eof()"<<endl;
else
cout<<"cin not end of file"<<endl;
if (st_data.good())
cout<<"cin ()"<<endl;
else
cout<<"cin not good()"<<endl;
}
int main()
{
// cout<<"检查cin的状态"<<endl;
// // 00011100
// //cin.setstate(istream::badbit);
// //cin.setstate(istream::failbit);
// //cin.setstate(istream::badbit | istream::failbit);//可同时改变2个
// //cin.setstate(istream::badbit);
// //cin.clear(istream::badbit);
// //cin.clear()
// //istream::iostate old_state=cin.rdstate(); //使用流,使用后恢复
// //cin.clear()
// check_cin_state(cin);
//
// cout<<"请输出一个整数"<<endl;
// int n;
// cin>>n;
//
// cout<<"检查cin的状态"<<endl;
// check_cin_state(cin);
//
检查cin的状态
cin not bad()
cin not fail()
cin not end of file
cin ()
请输出一个整数
5
检查cin的状态
cin not bad()
cin not fail()
cin not end of file
cin ()
int sum=0,value;
// //简单方法
// cout<<"请输出整数,clion中ctrl+D结束"<<endl;
// while(cin>>value) //输出字符aa,循环结束
// {
// sum+=value;
// cout<<"sum is "<<sum<<endl;
// }
输出
请输出整数,clion中ctrl+D结束
12
sum is 12
24
sum is 36
15
sum is 51
^D
//更好的方法
while(cin>>value,!cin.eof()) //逗号右侧为判断条件
{
if (cin.bad())
{
throw std::runtime_error("IO stream corrupted");
}
if (cin.fail())
{
cerr<<"bad data,try again"<<endl;
cin.clear(); //忽略流的状态
cin.ignore(200,'\n') ; // 忽略200个或者遇到\n结束
continue;
}
sum+=value;
cout<<"sum is "<<sum<<endl;
}
// 输出
// 15
// sum is 15
// 35
// sum is 50
// df
// bad data,try again
// 32
// sum is 82
// 34
// sum is 116
// ^D
//
return 0;
}
8.2.1_文件输入输出-文件流对象
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
/********************************************************************
8.2.1 文件输入输出-文件流对象
**********************************************************************/
void print_1(string s1)
{
cout<<s1<<endl;
}
int main()
{
string file_name("new_txt_cpp.txt");
ofstream outfile(file_name.c_str()); //c_str c风格字符串
// ofstream outfile("new_txt_cpp.txt"); //创建一个txt文件,功能同上面
outfile<<"hello,cpp!\n"
"hello,c++!\n"
"hello!";
outfile.close();
// ifstream infile("new_txt_cpp.txt"); //打开一个txt文件
ifstream infile; //流对象infile,没有和一个文件绑定
infile.open(file_name.c_str());
if (!infile){
cerr<<"erro:不能打开文件"<<file_name<<endl;
return -1;
}
string s;
// infile状态是end of file
while(infile>>s) //读取文件
cout<<s<<endl; //流状态还是eof
infile.close(); //关闭文件
infile.clear(); //不清除导致不能重新读新的文件
// 输出
// hello,cpp!
// hello,c++!
// hello!
vector<string> filenames;
filenames.push_back("one.txt");
filenames.push_back("two.txt");
filenames.push_back("three.txt");
cout<<"新建3个txt文档"<<endl;
for (vector<string>::const_iterator i=filenames.begin();i!=filenames.end();++i)
{
ofstream outfile(i->c_str()); //c_str c风格字符串
outfile<<*i+" hello,cpp! \n";
outfile<<*i+" hello,c++!\n" ;
// outfile<<*i+" hello! ";
outfile.close();
cout<<*i<<endl;
}
cout<<"输出3个txt文档内容"<<endl;
for (vector<string>::const_iterator itr=filenames.begin();itr!=filenames.end();++itr)
{
ifstream input(itr->c_str()); //c_str c风格字符串
if(!input)
{
cerr<<"错误:不能打开文件"<<*itr<<endl;
input.clear();
++itr;
continue;
}
while (input>>s)
print_1(s) ;
input.close();
input.clear();
}
// 新建3个txt文档
// one.txt
// two.txt
// three.txt
// 输出3个txt文档内容
// one.txt
// hello,cpp!
// one.txt
// hello,c++!
// two.txt
// hello,cpp!
// two.txt
// hello,c++!
// three.txt
// hello,cpp!
// three.txt
// hello,c++!
return 0;
}
8.2.2_文件输入输出-文件模式
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
/********************************************************************
8.2.2 文件输入输出-文件模式
**********************************************************************/
int main()
{
vector<string> filenames;
filenames.push_back("one.txt");
filenames.push_back("two.txt");
filenames.push_back("three.txt");
cout<<"新建3个txt文档"<<endl;
for (vector<string>::const_iterator i=filenames.begin();i!=filenames.end();++i)
{
ofstream outfile(i->c_str()); //c_str c风格字符串
outfile<<*i+" hello,cpp! \n";
outfile<<*i+" hello,c++!\n" ;
outfile.close();
cout<<*i<<endl;
}
string s_aa;
ifstream ifs("one.txt",ifstream::in); //ifstream::in为以读的方式打开文件(文件模式)
ifs>>s_aa;
ifs.close();
cout<<"输出文件内容"<<endl; //输出 输出文件内容
cout<<s_aa<< endl; // 输出 one.txt
ofstream ofs("file_a.txt",ofstream::out);//ofstream::out为以写的方式打开文件(文件模式)
ofs<<"this is file_a first!"<<endl;
ofs.close();
ofs.clear();
ofstream doc1("file_a.txt",ofstream::out);//ofstream::out为以写的方式打开文件(文件模式),文件不做清空
// ofstream doc1("file_a.txt",ofstream::out | ofstream::trunc); //与上一句相同功能,截断模式,清空文件内容
doc1<<"this is file_a second !"<<endl;
doc1.close();
doc1.clear();
ofstream txt1("two.txt");
// fstream txt1("two.txt",fstream::in | fstream::out); //功能同上一句,既可以输入又可以输出
txt1<<s_aa;
cout<<"输出two.txt内容:"<<endl; //输出 输出two.txt内容:
cout<<s_aa; //输出 two.txt
txt1.close();
txt1.clear();
// ifstream txt3("three.txt",ofstream::ate); //打开文件定位到文件结尾
ofstream txt3("three.txt",fstream::in | fstream::out | ofstream::ate); //功能同上一句,既可以输入又可以输出
string s_bb="pl_information1";
txt3<<s_bb<<endl;
txt3.close();
txt3.clear();
return 0;
}
8.3_字符串流
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
/********************************************************************
8.3 字符串流
**********************************************************************/
int main()
{
// //cout是流对象,ostream
// cout<<"hello"<<endl;
//
// //file1是文件输出流对象,文件流输入到文件中
// ofstream file1("test1.txt");
// file1<<"hi!"<<endl;
// file1.close();
//
// //ostr1 字符串输出流,写入内存
// ostringstream ostr1;
// ostr1<<"hell!!!"<< endl;
// cout<<"显示字符串流里面的字符串"<<ostr1.str()<< endl;
//
//
// ostringstream vip_msg;
// vip_msg<<"姓名: "<<"zhangfei"<<"\n"<<"age: "<<22<<"\n"<<"weight: "<<"135.90"<<"\n";
// cout<<"显示张飞信息:\n"<<vip_msg.str()<< endl;
输出
显示张飞信息:
姓名: zhangfei
age: 22
weight: 135.90
//
//
// string temp;
// string name;
// int years;
// float kilos;
//
// istringstream input_info(vip_msg.str());
// input_info>>temp;
// input_info>>name;
// input_info>>temp;
// input_info>>years;
// input_info>>temp;
// input_info>>kilos;
//
// cout<<"读到的结果:"<<endl;
// cout<<name<<endl;
// cout<<years<<endl;
// cout<<kilos<< endl;
输出
读到的结果:
zhangfei
22
135.9
string file_name,str1,word;
vector<string> s_vec1;
istringstream istream1;
cout<<"在cmake-build-debug文件夹新建text1.txt文档";
file_name="text1.txt";
ifstream file1(file_name.c_str());
if (!file1) return -1;
while (getline(file1,str1))
{
s_vec1.push_back(str1);
}
file1.close();
for (vector<string>::const_iterator iter1= s_vec1.begin();iter1!=s_vec1.end() ; ++iter1) {
// cout<<*iter1<<endl; //将原文复制显示
istream1.str(*iter1);
while(istream1>>word)
{
cout<<word<<endl; //一行字符串显示为一个一个单词
}
istream1.clear();
}
return 0;
}