c++学习笔记

这篇C++学习笔记涵盖了基本语法如字符串操作、循环控制、浮点数格式、switch语句、文件I/O,深入讲解了指针、引用、面向对象特性,包括类的构造函数、拷贝构造、继承、虚基类、常量对象以及异常处理。此外,还探讨了STL中的结构体和set的使用,并举例展示了如何应用lower_bound。
摘要由CSDN通过智能技术生成

c++学习笔记

by jokersio

关于语法:

字符串相关
  • getline(cin,s) 可以string和char
  • cin.getline() 只能char
string部分函数
string s
s1=s.substr(st,len) //从st位置开始截取一段长度为len的字串
s.c_str() //将string转换为char *类型
strcmp(s1,s2) //比较字符串大小,s1==s2 返回0,s1<s1 返回负数, s1>s2 返回正数
for_each:(用auto)
  • for(type v:array)修改不反应

  • for(type &v:array)修改反应到array里

printf 格式控制
printf("%-8d",i); //左对齐共占8个字符
printf("%+5d",i); //右对齐共占5个字符
printf("%04d",x);//保持四位数不满用前导0补
cout浮点数格式控制
#include<iostream>
#include<iomanip> //输出流控制,setiosflags(ios::fixed),setprecision(n)的头文件
using namespace std;
int main()
{
	double n = 50.26548;
	printf("%.4f", n); 
    cout << endl; //打印输出小数点后4位,会四舍五入

	cout << setprecision(4) << n << endl;//输出4位有效数字,包括整数和小数部分,会四舍五入 
	cout << setiosflags(ios::fixed) << setprecision(4) << n << endl;
    //输出小数点后4位,会四舍五入,会影响后面的setprecision()输出
	cout << setprecision(4) << n << endl;
    //受前面影响,只输出小数点后4位,而不再是包括整数部分的7位,会四舍五入

	cout << setiosflags(ios::fixed) << setprecision(4)<<floor(n * 10000)/10000<< endl;//不会四舍五入,保留几位小数就乘和除10的几次方
	system("pause");
	return 0;
}
switch 语法
switch(x) //x只能为int
{
    case 1:
        {
         	x++;
            break;
        }
    case 2:
        {
         	x--;
            break;
        } 
    default: cout<<"ha"; 
}
文件输入输出
//需要头文件fstream
ifstream fin("a.txt");
string a;
fin >> a;//从文件输入

ofstream fout("a.txt");
fout << "hello";  //输出到文件里
cout << "hello";  //输出到控制台

//需要头文件stdio.h
freopen("a.txt","w",stdout);
freopen("a.txt","r",stdin);
判断类型
typeid(a)==typeid(float)

指针与引用

引用调用

替代指针的技术(LJ推荐)

如果要传数组就用array和vector

改变参数的值
bool div(double a,double b,double& c)
{
    if(!b)
        return 0;
    c=a/b;
    return true;
}

//调用 
bool flag=div(a,b,c);
//就不用加指针了
//会改变主函数变量中c的值
传递大参数
void donothing(vector<int> &b)
{
}
int main()
{
    vector<int> a(1000000);
    donothing(a);
}
全部使用引用
//全部加引用没有损失,如果是只读参数加const
bool div(const double a,const double b,double& c)
{
    if(!b)
        return 0;
    c=a/b;
    return true;
}
const指针
找距离const最近的变量类型const int* p  
*p不能改 p可以改int* const p  
*p可以改 p不能改
左值引用与右值引用

左值就是正常的引用,右值是引用常量

int &&r=10

面向对象

结构和类辨析
  • 结构:默认是public,有构造函数(默认)
  • 类:默认是private,无构造函数(需声明)
类的一些注意事项
  1. 类加上了const之后

    任何修改成员变量的函数无法调用

    如果要调只读函数需要加const

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9P6ISfNc-1627004043427)(C:\Users\kevin\Desktop\c++学习笔记\const类只读.png)]

  2. this指针(类比python中的self)

  3. enum{maxn=10} //用枚举定义常量

  4. 静态成员函数不允许访问成员变量(只能访问静态变量)

  5. 构造函数用初始化列表的情况():如果会被继承,或者会被引用调用

   rent(int w,int h):width(w),height(h)
   {
       
   }
友联函数(c++特有不推荐)
class car{
	public:
		int b;
		friend int totalweight(boat n,car m);//友元函数的定义,friend+返回值类型+函数名+(参数) 
}

只要在类里声明,但不是类的成员函数

在主函数里正常调用

之后在外部写定义时可以调用private

// 正常应该写一个函数返回private变量的值

重载运算符
类内部写法
class student{
private:
	string name;
    int score;
    //在内部写默认第一个变量为this指针
public:
    int operator +(const node &a)
    {
        return this->score+a.score;
    }    
}    
输入输出输出运算符重载
ostream&operator<<(ostream& os,const Complex &c)
{
    os<<c.u<<"+"<<c.v<<"i";
    return os;
}

istream&operator<<(isstream& is,Complex &c)
{
    is>>c.u>>c.v;
    return is;
}
//注意os时后面要加const,istream不加const
//在类里调用时,一般要写成友联
重载++
MyTime MyTime::operator ++()
{
    second++;
    if(second==60){minute++;second=0;}
    if(minute==60){hour++;minute=0;}
    hour%=24;
    return *this;
}
构造函数中使用new和delete的注意事项
  • 如果在构造函数中使用new初始化指针成员,则应在析构函数中使用delete
  • new和delete对应,new[]和delete[]对应
  • 如果有多个构造函数,应使用相同的方式使用new,因为析构函数只有一个
拷贝构造函数
class Complex{
public:
    double real, imag;
    Complex(double r,double i){
        real = r; imag = i;
    }
    Complex(const Complex & c){
        real = c.real; imag = c.imag;
        cout<<"Copy Constructor called"<<endl ;
    }
};

调用情况:

  1. 当用一个对象去初始化同类的另一个对象
   Complex c2(c1);
   Complex c2 = c1;
   //两条语句等价
  1. 如果函数的返冋值是类 A 的对象,则函数返冋时,类 A 的复制构造函数被调用。
   A Func() {
       A a(4);
       return a;
   }
  1. 如果函数 F 的参数是类 A 的对象,那么当 F 被调用时,类 A 的复制构造函数将被调用。
   void Func(A a){ }
深拷贝与浅拷贝
int main()
{
    int *a=new int[10];
    int *b=a;//浅拷贝
    
    //深拷贝
    int *c=new int[10];
    for(int i=0;i<10;i++)
        c[i]=a[i]}
类继承

并不推荐使用。相较于继承,更推荐使用组合。

c++的继承机制较java与python更为复杂,也更容易出现bug,比如一个类可以继承两个父类。

可以类比python的继承方式。

  • 继承构造函数
class sqare:public rent{
public:
    square(int w):rent(w,w){
        
    }
}
  • public继承可以继承public 和protected
  • protected和private继承(有表)(最好不要用)
虚基类

由于C++支持多重继承,所以对于一个派生类中有几个直接父类,而几个直接父类中有几个可能分别继承自某一个基类(就是父类的父类),这样在构造最终派生类时,会出现最终派生类中含有多个同一个基类的情况,就会产生二义性的问题(不知道该调用哪个基类的成员变量和函数),为解决此问题,需要使用虚基类,即只对此基类生成一块内存区域,这样最终派生类中就只会含有一个基类了 。

class   A   { 
    public: 
        void   printA()   {cout<<"this   is   A\n";} 
}; 
class   B:virtual   public   A; 
class   C:virtual   public   A; 
class   D:public   B,public   C; 
常量

常量对象调用函数时,只能调用常量函数

void Test(const CAR &x)
{
    x.Show();
}

将show函数申明为常量

void Show() const

关于STL

结构体lower_bound(内部重载运算符)
#include<bits/stdc++.h>
using namespace std;
int n;
struct node{
	int val,id;
	bool operator < (const node &b) 
    {
		if(val!=b.val) 
			return val<b.val;
		else 
			return id<b.id;
	}
}a[100000+50];
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i].val),a[i].id=i;
	sort(a+1,a+n+1);
	cout<<lower_bound(a+1,a+n+1,(node){-100,0})-a<<endl;
	cout<<lower_bound(a+1,a+n+1,(node){-2,0})-a<<endl;
	cout<<lower_bound(a+1,a+n+1,(node){1,0})-a<<endl;
	cout<<lower_bound(a+1,a+n+1,(node){100,0})-a<<endl;
}
关于set

是天梯赛L1-005的题解,set模板应用

#include<bits/stdc++.h>
#define MAXN 110
#define for1n(i, n) for (int i = 1; i <= n;i++)
using namespace std;
 
int m,n,num[MAXN];
set<int> u[MAXN];
 
void query(int x,int y)
{
    int same=0;
    for(auto id:u[x])
    {
        if(u[y].find(id)!=u[y].end())
            same++;
    }
    int sum=u[x].size()+u[y].size();
    int nt=sum-same;
    printf("%.2lf%%\n",same*1.0/nt*100);
}
int main()
{
    cin>>n;
    for1n(i,n)
    {
        cin>>num[i];
        for1n(j,num[i])
        {
            int x;
            cin >> x;
            u[i].insert(x);
        }
    } 
    cin>>m;
    
    for1n(i,m)
    {
        int x,y;
        cin >> x >> y;
        query(x, y);
    }
    cin.get();
}

杂类知识

多文件编程
  • .h文件放函数声明
  • .cpp文件放函数的定义
  • .hpp声明实现都有,可以减少cpp文件的数量
  • 编译时将所有的cpp文件一起编译
内联函数
  • 在声明和定义前加inline

  • 不能递归,编译出来的exe较大

  • 一般是简单函数

  • 提高调用速度,节省空间

  • 实现在头文件里

异常检测

传统处理:(推荐)

  • abort()或exitshiyo()退出程序
  • 函数返回“错误码”

异常机制:

  • 引发异常
  • 捕获异常
  • 使用try
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值