• c++


    java程序是半编译半解释的,目的是为了跨平台。C++程序是直接编译为本地机器语言代码。

    R进制转十进制:各位数字与权相乘,积相加;十进制转R进制:除以R取余;十进制小数转R进制小数:乘以R取整;

    补码:0的表示唯一,符号位可以直接参与运算。正整数原码就是补码,负整数补码是反码加一

    反码:符号位不变,其余各位取反

    字符表示:ASCII码;汉字编码:中国国家标准GB18030

    在生成发布版本之前,需要清楚早期生成过程中创建的中间文件和输出文件,确保其是最终版本

    C++:在C的基础上支持面向对象的方法

    整数类型:signed unsigned short long long long

    浮点数类型:float double long double

    用字符数组存储字符串,通常使用C++类库中的string类

    浮点常量默认为double型,如果后缀F(或f)可以使其成为float型

    符号常量,定义时一定要初始化,在程序中间不能改变其值 const 只能用不能修改

    浮点数是近似存储的,比如赋值3.14159可能会存储为3.14158999999999

    两个整数相除结果取整。

    优先级:非! 与&& 或||

    按位与(&),按位或(|),按位异或(^)——与0异或保持原值,与1异或取反,按位取反(~),左移<<——底位补0,高位舍弃,相当于乘2,右移>>——低位舍弃,高位无符号则补0,有符号则补符号位,相当于除以2

    一些二元运算符要求两个操作数类型一致,如果不一致编译系统会自动对数据进行转换,基本原则是低类型数据转换为高类型数据

    step into 遇到函数调用时会进入到函数的内部,step over直接看到函数返回的结果

    UML图

    一个工程可以划分为多个源文件,如类声明文件(.h)、类实现文件(.cpp),类使用文件(main()所在的.cpp)。利用工程组合各个文件。

    比如point.h文件定义point类,point.cpp文件实现point类,5_10.cpp使用point类

    如果一个变量在其他文件中需要使用,可以使用extern关键字声明

    标准c++库为我们提供了:输入/输出类、容器类与抽象数据类、存储管理类、算法、错误处理、运行环境支持

    编译预处理:#include<> #include "" define undef

    基础

    #include<iostream>	
    #include<cmath>//库中提供了很多常用的函数,使用系统函数时要包含相应的头文件
    
    using namespace std;//命名空间可以避免重名
    
    //函数的调用在函数的定义之前,需要进行函数原型的声明
    double power(double x,int n=6);//预先设置函数参数的默认值,有默认参数的形参必须在参数列表的最右,如果一个函数有原型声明,且声明在定义之前,则默认参数值应该在原型声明中给出
    
    
    //内联函数,对于部分简单函数,不需要转子函数再返回这个开销,告诉编译器编译时直接把函数体里计算代码替换到函数调用点,节省了参数传递,控制转移等开销。内联函数不能有循环和switch,定义必须在内联函数第一次被调用之前,不能进行异常接口声明
    inline double calArea(double radius){
        return 3.14*radius*radius; 
    }
    
    //constexpr函数如果所有参数都是常量表达式时其返回的也一定是常量表达式
    constexpr int get_size(){return 20;}
    
    //函数重载,形参或返回值类型不同或个数不同,但功能相同,其中形参必须不同,且功能必须相同
    int add(int x,int y){return x+y;}
    float add(float x,float y){return x+y;}
    
    
    
    
    
    int main{
        int a,b,x;
        const double pi=3.14159;
        cout<<"Hello!"<<endl; <<是一个流插入运算符,endl表示行结束
        cin>>radius;
        return 0;
        a=3*5,a*4;//逗号表达式,最终结果为后面一个表达式的值,即60
        x = a>b?a:b;//条件表达式,如果为真则为a,如果为假则为b
        sizeof(x);//返回占的字节数
        static_cast<int>(z);//类型转换,等价于int(z)或(int)z
        cout<<setw(5)<<setprecision(3)<<3.1415;//一些I/O流类库操作符,设置域宽和设置浮点数小数位
        
        if(x>y)cout<<x;
        cin>>day;
        
        switch(day){
        case0:cout<<"sunday"<<endl;break;//如果没有break还会往下顺序执行
        default:cout<<"day out of range"<<endl;break;        
        }
        
        int i=1,sum=0;
        while(i<=10){
            sum+=i;
            i++;
        }
        
        do{
            sum+=i;
            i++
        }while(i<=10);//无论while是否满足都会执行一次
        
        for(int k;k<=n;k++)
            if(n%k==0)
                cout<<k<<' ';
        
        double pow;
        pow = power(5,2);
        
        typedef double Area;//为已有类型另外命名
        enum Weekday
        {SUN=7,MON=1,TUE,WED,THU,FRI,SAT}//枚举元素默认值为0,1...可另行声明,枚举值可以进行关系变量
        
        //函数在调用时才给形参分配存储单元,可以用函数参数的双向传递把函数的多个结果返回(return只能返回一个),值传递实现单向传递,引用传递实现双向传递
        int &ri=i;//引用(&)是标识符的别名,这里定义inty引用ri,并初始化为变量i的引用,定义引用时必须初始化,使它指向一个已存在的变量,一旦一个引用被初始化后就不能改为指向其他变量
        j = 10;
        ri=j;//两个名字指向同一个变量,相当于i=j
        swap(x,y);//定义swap时使用引用作参数,用以实现双向传递
        
        constexpr int foo =get_size();//get_size使用constexpr修饰,所以foo也要时constexpr
        
    
        
    }
    
    void swap(int&a,int&b){//一般引用用在形参上实现函数的双向传递
        int t=a;
        a=b;
        b=t;
    }
    
    //实参参数类型相同但个数不确定时,可以传递一个名为initializer_list的标准库类型,其对象的类型永远是常量值,我们无法改变initializer_list对象中元素的值。如果实参的类型不同,我们可以编写可变参数的模板
    
    
    double power(double x,int n){
        double val =1.0;
        while(n--)
            val*=x;
        return val;
    }
    

    面向对象

    //变量和对象定义在不同位置(函数体内、类体内、函数原型参数表内、所有函数和类之外)其作用域、可见性、生存期都不同
    //函数原型作用域:函数原型中的参数
    //局部作用域:函数的形参、在块中声明的标识符
    //类作用域:包括类体和成员函数体,在类作用域以外访问类的成员时,通过类名或该类的对象名、对象引用访问。对非静态成员还可用对象指针访问
    //文件作用域:不在上述各个作用域中出现的声明,其作用域开始于声明点,结束于文件尾
    //可见性:如果标识符在某处可见,就可以在此处引用该标识符。如果某个标识符在外层中声明,且在内层中没有同一标识符的声明,则在内层中可用,如果内层声明了与外层作用域中同名的标识符,则外层的标识符在内层不可见
    
    //静态生存期:生存期与程序的运行期相同。在文件域中声明的对象有这种生存期,在函数内部声明静态生存期对象,要冠以关键字static,比如说来Point类中创立一个count的static成员,用于记录点的总数。构造函数中count++,析构函数中count--(这里可见析构函数的作用) 
    //动态生存期:开始于声明点,结束于命名该标识符的作用域结束处。块作用域中声明的,没有用static声明的对象。
    
    //友元:对一些类外的函数、其他的类给与授权,使之可以访问类的私有成员,同时可以使用const关键字对共享数据限制修改。友元函数用friend声明,在它的函数体中能通过对象名访问private和protect成员。如果一个类是另一个类的友元,则此类的所有成员都能访问对方类的私有成员,注意类的友元关系是单向的
    
    //为了保护共享数据,我们可以定义常对象、常成员(常数据成员、常成员函数)、常引用,都是用const修饰。常成员函数保证不改变对象的状态,可以用来处理常对象。常引用只能读取对象的内容不能修改。
    #include<iostream>
    
    
    class Clock{
        public://公有成员(外部接口)
        	Clcok()=default;//指示编译器提供默认构造函数
        	Clock(int newH,int newM,int newS)//构造函数,构造函数是类中的特殊函数,用于描述初始化算法,在对象创建时被自动调用,如果程序没有定义构造函数,编译器会自动生成一个默认构造函数
           	
        	void setTime(int newH=0,int newM=0,int newS=0);
        	void showTime();
        private://私有成员
        	int hour = 0,minute=0,second=0;//类内初始值
    };
    
    Clock::Clock(int newH,int newM,int NewS)://定义构造函数
    	hour(newH),minute(newM),second(newS){//初始化列表,对类的成员初始化时用这种方式
        }
    Clock::Clock()://默认构造函数,无参数,防止创建对象时没有给出参数。
    	hour(0),minute(0),second(0){}
    //以上两个构造函数可以用委托构造函数简化,还可以保持代码的一致性
    
    void Clock::setTime(int newT,int newM,int newS){
        hour = newH;
        minute=newM;
        second=newS;
    }
    void Clock::showTime(){
        cout<<hour<<":"<<minute<<":"<<second;
    }
    
    
    
    class Point{
    	public:
    		Point(int xx = 0, int yy = 0) { x = xx; y = yy;count++; }//构造函数
    		Point(Point &p){x=p.x,y=p.y;count++;}//复制构造函数
        	~Point();{count--;}//析构函数
    		int getX() { return x; };
    		int getY() { return y; };
       		friend float dist(const Point &a,const Point &b)//定义友元函数dist,这里用到了常引用,防止引用双向传递时进行了修改
    	private:
    		int x, y;
        	static int count;//静态数据成员count用于记录Point的总数。
    };
    
    Point::Point(const Point &p){//复制构造函数是一种特殊的构造函数,其形参为本类对象的引用,作用是用一个已存在的对象去初始化同类型的新对象
        x=p.x;
        y=p.y;
    }
    Point::~Point(){}//析构函数完成对象被删除前的一些清理工作,会在函数消亡时自动调用,如果没有声明析构函数,编译器也会自动产生默认析构函数,其函数体为空
    
    void fun1(Point p){//形参为Point类的函数
        cout<<p.getX()<<endl;
    }
    
    Point fun2(){//返回值为Point类的函数
        Point a;
        return a;
    }
    
    float dist(const Point&a,const Pount&b){
        double x =a.x-b.x;
        double y =a.y-b.y;
        return static_cast<float>(sqrt(x*x+y*y))
    }
    
    //类的组合,即类中的成员是另一个类的对象。
    class Line {
    	public:
    		Line(Point xp1, Point xp2);
    		Line(Line &l);
    		double getLen() { return len; }
    	private:
    		Point p1, p2;
    		double len;
    };
    Line::Line(Point xp1, Point xp2) : p1(xp1), p2(xp2) {//组合类构造函数
    	cout << "Calling constructor of Line" << endl;
    	double x = static_cast<double>(p1.getX() - p2.getX());
    	double y = static_cast<double>(p1.getY() - p2.getY());
    	len = sqrt(x * x + y * y);
    }
    Line::Line (Line &l): p1(l.p1), p2(l.p2) {//复制构造函数
    	cout << "Calling the copy constructor of Line" << endl;
    	len = l.len;
    }
    
    int main{
        Clock myclock;//对象是类的实例,这里定义对象
        myclock.setTime(8,30,30);
        myclock.showTime();
        
        CLock c1(0,0,0);//自动调用有参数的构造函数
        Clock c2;//调用无参数的构造函数
        c.showTime;
        
        Point a;//使用复制构造函数的三种情况
        Point b(a);//情况一,用a初始化b,第一次调用复制构造函数
        fun1(b);//情况二,对象b作为fun1的实参。第二次调用复制构造函数
        b=fun2();//情况三,函数的返回值是类对象,函数返回时,调用复制构造函数
        
        Point myp1(1, 1), myp2(4, 5);//建立Point类的对象
    	Line line(myp1, myp2);//建立Line类的对象,形实结合传参数的时候,先从后面开始传
    	Line line2(line);//利用复制构造函数建立一个新的对象,用已经构造好的line初始化line2
    	cout << "The length of the line is:";
    	cout << line.getLen() << endl;
    	cout << "The length of the line2 is:";
    	cout << line2.getLen() << endl;
    	return 0;
    }
    
    //因为类应该先声明,后使用,两个类互相引用时,使用前向引用声明
    class B;//前向引用声明,但是注意在提供一个完整的类之前,不能声明该类的对象,在使用时不能涉及类的任何细节
    ...
    class B{...}
    
    //结构体是一种特殊的类,与类的区别是:类的缺省访问权限是private,结构体的缺省访问权限是public,结构体定义主要用来保存数据,而没有什么操作的类型。结构体中可以有数据成员和函数成员
    #include <string>
    using namespace syd;
    struct Sdudent{
        int num;
        string name;
        char sex;
        int age;
    }
    Sdudent stu = {97001,"lin lin",'F',19};
    
    //联合体,成员公用一组内存单元,任何两个成员不会同时有效
    union Mark{//成绩只能选择其中一种形式
        char grade;
        bool pass;
        int percent;
    }
    
    //枚举类,作用:作用域限制在枚举类、转换限制、可以指定底层类型
    enum class Type:char{General,Light,Medium,Heavy};//不定义底层类型时默认是int
    enum class Side{right,left};
    enum class Thing{wrong,right};
    int main(){
        Side s=Side::right;
        Thing w=Thing::right;//使用枚举类时不会冲突,使用普通枚举类型则会冲突
    }
    
    

    数组

    //数组在内存中顺次存放,它们的地址是连续的,数组名是数组元素的首地址
    
    //数组名作参数,形、实参数都是数组名,类型要一样,传送的是数组首地址
    #include <iostream>
    using namespace std;
    int main(){
       int a[10],b[10];//没有初始化时,局部作用域的非静态数组会存在垃圾数据,static数组中的数据默认为0
       static int c[10]={0,1,2,3,4};
       static int d[]={0,1,2,3,4};
       static int e[3][4]={{1},{5,6},{9,10}}//可以只对部分元素初始化,此时剩下的未初始化的元素为0
       static int f[][2]={{1,2},{3,4}}//第一维的下标数可以省略
       Point a[2]={Point(1,2),Point(3,4)};//对象数组中每一个元素对象被创建时,系统都会调用类构造函数初始化该对象
       int array[3]={1,2,3};
       for(int &e:array){...}//基于范围的for循环
    }
    

    指针

    //c++内存空间的访问方式:1.通过变量名访问	2.通过地址访问
    //指针:内存地址,用于间接访问内存单元。	指针变量:用于存放地址的变量
    static int i;
    static int* ptr =&i;//&表示获取i的地址,然后用i的地址初始化ptr,*表示正在定义的变量是一个指针,同时还要表示指针指向的对象是int类型
    *ptr=3;//*表示指针运算,也就是一个寻址的过程,即把3赋值到ptr的地址指向的单元,&返回的是一个地址,所以它们其实互为逆运算
    //0可以赋值给指针,表示空指针。允许定义void类型的指针,该指针可以被赋予任何类型对象的地址
    #include <iostream>
    using namespace std;
    int main(){
        int i;
        int*ptr=&i;
        i=10;
        void pv;//不能声明void类型的变量,但是可以声明void类型的指针
        const int*p1=&i;//p1是指向常量的指针
        int j;
        p1=&j;//正确,p1本身的值可以改变
        *p1=1;//编译时出错,不能改变p1所指的对象
        int * const p2=&i;
        p2=&j;//错误,p2是指针常量,值不能改变
        //指针的加减运算意义是指向位置的前方或后方第n个数据的起始位置,++、--意义是指向下一个h或前一个完整数据的开始。当指针指向连续存储的同类型数据时,以上才有意义
        short a[4];
        short *pa=a;//数组名就是起始地址,*pa等同于a[0],*(pa+1)等同于a[1]
        //指针可以和零之间进行等于或不等于的关系运算。表示判断指针是否为空指针
        
        //用指针存放二维数组,可以存放不同列的二维数组
        int line1[]={1,0,0};
        int line2[]={0,1,0};
        int line3[]={0,0,1};
        int*pline[3]={line1,line2,line3};//pline[i]相当于指针数组第i个元素,所以可以用pline[i][j]索引
        
        //用指针作函数参数:数据需要双向传递时;当传递一组数据时,只传首地址运行效率比较高
        
        int* function(){};//指针类型的函数,就是返回值是指针的函数。注意不要将非静态局部地址作为函数返回值,应该返回到主调函数后依然合法有效的地址。正确操作应该是在主函数中定义的数组在子函数中操作后返回其中一个元素的数组
        int(*func)();//函数指针,指向函数的指针,指向的是程序代码存储区。典型用途是实现函数回调,把一个函数作为另一个函数的参数
        //对象指针,指向一个对象的地址,通过指针访问对象成员,ptr->getx()相当于(*ptr).getx()
        Point a(4,5);
        Point *p1=&a;
        
        //动态内存分配,体现指针的作用
        Point *ptr1=new Point;
        delete ptr1;//不是删除指针自己,而是删除指针所指对象
        
        Point*ptr=new Point[2];//动态创建对象数组
        ptr[0].getx();
        delete[] ptr;//删除整个对象数组
        
        //动态数组。。。
        
        //vector:封装任何类型的动态数组,自动创建和删除,还能进行数组下标越界检查
        vector<int>v={1,2,3};
        cout<<v[1];//可以直接下标索引
       	v.size();//vector可以直接求size
        for(auto i=v.begin();i!=v.end();++i)
            cout<<*i<<endl;
        for(auto e:v)
            cout<<e<<endl;
        
        //浅层复制:实现对象间数据元素的一一对应复制。深层复制:被复制的对象是指针类型时,不是复制该指针成员本身,而是将指针所指对象进行复制。
        
        class_name(class_name &&);//移动构造:将源对象的资源控制权全部交给目标对象(相当于剪切),&&是右值引用,即将消亡的值是右值,函数返回的临时变量是右值
        
        const char*string1="program";//字符串。字符串常量各字符连续、顺序存放,每个字符占一个字节,以''结尾,相当于一个隐含创建的字符常量数组,字符串常量出现在表达式中表示这一字符数组的首地址,首地址可以赋值给字符常量指针。这是c风格的字符串
        string s1="program"//string类,可以用+、=、==以及各种不等号,还可以下标索引
        stirng city,state;
        getline(cin,city,',');//getline可以输入整行字符串,输入字符串时可以使用其他分隔符作为字符串结束标志
        getline(cin,state);
    }
    

    类的继承

    //保持已有类的特性而构造新类的过程称为继承
    //在已有类的基础上新增自己的特性而产生的新类称为派生
    //被继承的已有类称为基类(或父类)
    //派生出的新类称为派生类(或子类)
    //直接派生出某类的基类称为直接基类
    //基类的基类甚至更高层的基类称为间接基类
    //派生类可以吸收基类成员、改造基类成员、添加新的成员。默认情况下包含了全部基类中除构造和析构函数之外的所有成员。可以用using语句继承基类构造函数
    //三种继承方式:公有继承、私有继承、保护继承
    
    //公有继承:private成员不可直接访问,可以通过公有访问接口去访问私有成员
    class Point{
    public:
       	void initPoint(float x=0,float y=0){this->x=x;this->y=y;}
        float getX()const{return x;}
        float getY()const{return y;}
    private:
        float x,y;
    }
    
    class rectangle:public Point{
    public://新增公有函数成员
    	void initrectangle(float x,float y,float w,float h){
            initpoint(x,y);//调用基类公有成员函数
            this->w=w;
            this->h=h;
        }    
        float getH()const{return h;}
        float getW()const{return w;}
    private://新增私有数据成员
        float w,h;
    }
    
    //私有继承:基类的public和protect成员都以private身份出现在派生类中,派生类的成员函数可以直接访问基类中的public和protect成员
    class rectangle:private Point{
    public://新增公有函数成员
    	void initrectangle(float x,float y,float w,float h){
            initpoint(x,y);//调用基类公有成员函数
            this->w=w;
            this->h=h;
        }    
        float getX()const{Point::getX();}//私有成员函数在类内可以使用
    private://新增私有数据成员
        float w,h;
    }
    
    //保护继承:基类的public和protect成员都以protected的身份出现在派生类中,派生类的成员函数可以直接访问基类的public和protected成员
    //protected成员的特点:对于建立其所在类对象的模块来说,它与private成员的性质相同,对于其派生类来说,他与public的性质相同 
    
    //派生类的构造函数:派生类的新增成员由派生类定义构造函数初始化,继承来的成员自动调用基类构造函数进行初始化,派生类的构造函数还要给基类构造函数传递参数
    class Derived:public Base2,public Base1,public Base3{
    public:
        Derived(int a,int b,int c,int d):Base1(a),member2(d),menber1(c),Base2(b){}
    private:
        Base1 member1;
        Base2 member2;
        Base3 member3;
    }
    
    //派生类的复制构造函数
    //派生类的析构函数
    //虚基类:virtual关键字,主要用来解决多继承时可能发生的对同一基类继承多次的二义性问题
    

    多态性

    //运算符重载:针对新类型的实际需要,对原有运算符进行适当的改造。"."、","、":"、"?:"不能重载,重载之后运算符的优先级和结合性都不会改变。
    //将运算符重载为成员函数
    //运算符重载为非成员函数,至少应该有一个自定义类型的参数
    
    //虚函数:指示编译器不要在编译阶段做静态绑定,要为运行阶段做动态绑定
    //如果打算允许其他人通过基类指针调用对象的析构函数,就需要让基类的析构函数成为虚函数,否则执行delete的结果是不确定的
    
    //虚表:每个多态类有一个虚表,虚表中有当前类的各个虚函数的入口地址,每个对象有一个指向当前类的虚表的指针
    //动态绑定
    
    //抽象类:不能实例化,规定对外接口的统一形式
    //override 
    //final,指明某类不运行被继承
    

    模板

    //函数模板,只有能够进行函数模板中运算的类型,可以作为类型实参。自定义的类需要重载模板中的运算符才能作为类型实参
    template<typename T>
    T abs(T x){
        return x<0?-x:x;
    }
    
    //类模板,可以为类声明一种模式,使得类中的某些数据成员、成员函数参数、成员函数返回值,能取任意类型
    template<typename T>
    class store{//类模板,实现对任意类型进行存取
    private:
        T item;//item用于存放任意类型的数据
        bool havevalue;//标记是否已被存入内容
    public:
        store();
        T &getElem();//提取数据函数
        void putElem(const T &x);//存入数据函数
    }
    
    
    //线性群体:多个数据元素组成的集合体,线性群体中的元素按位置排列有序,非线性群体不用位置顺序标识元素
    
    //结点类模板、链表类模板、栈类模板、队列类模板
    //选择排序、冒泡排序、二分查找、
    

    如果一个函数的返回值是一个对象的值,就是右值,不能成为左值。如果返回值为引用,由于引用是对象的别名,通过引用可以改变对象的值,因此是左值

    STL库

    //STL库基本组件:容器、迭代器、函数对象、算法
    //迭代器是容器和算法的桥梁
    //容器是包含一组元素的对象
    //迭代器:泛化的指针,用来访问容器中的元素
    //适配器:用已有对象提供新的接口的对象
    //容器的通用功能:支持关系运算符、begin()、end()、clear()、empty()、size()、s1.swap(s2)、S::iterator
    //顺序容器、集合、映射
    //函数对象
    

    流类库与输入输出

    //cout	cerr	clog
    
  • 相关阅读:
    Android进程启动
    Android 系统Framework
    每日一问 AIDL
    Android性能优化
    Android启动优化
    Android绘制优化
    Android布局优化三剑客#
    android性能优化全方面解析(一)
    Android网络
    Android四大组件
  • 原文地址:https://www.cnblogs.com/rjxu/p/13225868.html
Copyright © 2020-2023  润新知