美文网首页
C++语言简介

C++语言简介

作者: 薛落花随泪绽放 | 来源:发表于2022-08-28 11:10 被阅读0次

    一、C++语言的发展简史

    根据是否可以直接操纵计算机底层硬件,将程序设计语言分为低级语言中级语言高级语言

    机器语言和汇编语言都属于低级语言,能够直接操纵计算机的寄存器和内存。

    机器语言是使用机器指令的二进制代码编写程序,能够直接被计算机识别。

    汇编语言使用能够代表指令的助记符来编写程序,可以看作是符号化了的机器语言。

    高级语言是面向用户的语言。C++属于高级语言。

    在83年之前被称为带类的C语言。C语言是C++语言的前身。
    98年,C++的ANSI/ISO标准被投入使用,并在03年、11年、14年和17年发布了第二版、第三版、第四版和第五版。

    二、C++语言的特点

    C++语言是一种编译式的、通用的、大小写敏感的编程语言,完全支持面向对象的开发模式。

    主要特点是:

    1. 是C语言的继承,尽量兼容C语言,既保持了C语言的简介和高效,同时也增强了C语言对类型的处理。
      2.加入了面向对象的特征。

    一)、基本的输入/输出

    在C++语言中,类库中提供了输入流类istream和输出流类ostream。
    cin和cout分别是istream类和ostream类的对象,用来实现基本的键盘输入和屏幕输出。

    从输入流中获取数据的操作称为提取操作,向输出流中添加数据的操作称为插入操作。

    在C++中,可以使用流提取运算符“>>"从标准输入设备键盘取得数据。使用流插入运算符"<<"向输出设备屏幕输出信息。

    当程序中用到cin和cout时,需要在程序中包含头文件<iostream>。

    cin和cout一般格式

    cin>>变量1>>变量2>>...>>变量n;
    
    cout<<表达式1<<表达式2<<...<<表达式n;
    

    cin中的变量可以是任何基本类型的变量。以空格、制表符<Tab>键或<Enter>键作为空格符。如果第一个字符是空格、Tab或Enter,则cin会将其忽略并清除。
    例如,输出/输出示例程序1-1,

    #include <iostream>  //第1行
    #include <string>   //第2行
    using namespace std; //第3行
    int main()
    {
        int oneInt1,oneInt2;
        char strArray[20];
        string str;
        double oneDouble;
        char oneChar = 'a';
        cout<<"输入两个整型值,一个字符,一个字符串和一个浮点值,";
        cout<<"以空格、Tab键或<Enter>键分隔:"<<endl;
        cin>>oneInt1>>oneInt2>>oneChar>>strArray>>oneDouble;
        str = strArray;
        cout<<"输入的数据是:"<<endl;   //endl的作用是换行
        cout<<"字符串是:\t\t"<<str<<endl            //\t是制表符Tab
            <<"两个整型值分别是:\t"<<oneInt1<<" 和\t"<<oneInt2<<endl
            <<"字符是:\t\t"<<oneChar<<"\n"   //"\n"是换行符,与endl效果相同 
            <<"浮点值是:\t\t"<<oneDouble<<endl; 
        return 0; 
     } 
    
    image.png

    如果想将空格、制表符或<Enter>键输入给字符变量,可以使用getchar()函数。
    如果输出时双引号括起来的字符串太长了,可以在中间添加符号"".

    二)、头文件和命名空间

    在C++中,头文件不再以".h"结尾。常用的头文件

    标准输入输出流:<iostream>
    标准文件流:<fstream>
    标准字符串处理函数:<string>
    标准数学函数:<cmath>
    

    定义一个命名空间的语法格式

    namespace 命名空间名
    {
      命名空间内的各种声明(函数声明、类声明、...)
    }
    

    命名空间也称为名字空间。using namespace std;表示使用命名空间std。
    引用其他命名空间的标识符的语法格式:

    命名空间名::标识符名
    

    例如,如果没有using namespace std;,则需要分别使用全称std::cin、std::cout、std::string和std::endl等来指明命名空间std。
    using语句有两种形式:

    using 命名空间名::标识符名;
    using namespace 命名空间名;
    

    *三)、强制类型转换运算符

    static_cast用于将一种数据类型转换成另一种数据类型

    static_cast<类型名>(表达式)
    

    以程序1-1为例,下面4种都是正确的

    oneInt2 = static_cast<int>(oneDouble); //强制类型转换
    oneInt2 = int(oneDouble); //强制类型转换运算符的新形式
    oneInt2 = (int)oneDouble; //强制类型转换运算符的旧有形式
    oneInt2 = oneDouble; //自动类型转换
    

    const_cast用于去除指针和引用的常量性,但不能去除变量的常量性。

    const_cast<类型名>(表达式)
    

    例如,强制类型转换示例程序1-2

    #include <iostream>
    using namespace std;
    int main()
    {
        int a = 10;
        const int *p = &a;  //不能使用常量指针p修改a的值
        const int ca = 30;  //被const修饰
        int *q;
        cout<<"a的地址为:\t"<<&a<<"\ta的值为:\t"<<a<<endl;
        cout<<"*p指向的地址为:"<<p<<"\t*p的值为:\t"<<*p<<endl;
        q = const_cast<int *>(p);   //去除p的常量性赋给q,如果写q=p;会报错
        *q = 20;        //如果写*p=20;是错误的
        cout<<"a的地址为:\t"<<&a<<"\ta的值为:\t"<<a<<endl;
        cout<<"*p指向的地址为:"<<p<<"\t*p的值为:\t"<<*p<<endl;
        cout<<"*q指向的地址为:"<<q<<"\t*q的值为:\t"<<*q<<endl;
        cout<<"分界线"<<endl;
        p = &ca;    //ca的值不能修改
        q = const_cast<int *>(p);   //去除p的常量性赋给q,如果写q=p;会报错
        *q = 40;     //如果写*p=40;是错误的
        cout<<"ca的地址为:\t"<<&ca<<"\tca的值为:\t"<<ca<<endl;
        cout<<"*p指向的地址为:"<<p<<"\t*p的值为:\t"<<*p<<endl;
        cout<<"*q指向的地址为:"<<q<<"\t*q的值为:\t"<<*q<<endl;
        return 0;
     } 
    
    image.png

    四)、函数参数的默认值

    在C++中,可以在声明函数时为形参指定默认值。当调用有默认值的函数时,调用语句可以不给出对应的实参。
    例如,定义带默认值的函数程序1-3

    #include <iostream>
    using namespace std;
    void func(int a=11,int b=22,int c=33)   //为参数a,b,c分别设置了默认值11,22,33
    {
        cout<<"a="<<a<<",b="<<b<<",c="<<c<<endl;
     } 
     
    int main()
    {
        func();
        func(55);
        func(77,99);
        func(8,88,888);
        return 0;
    }
    
    image.png

    C++语言规定,提供默认值时必须按从右至左的顺序提供,即有默认值的形参必须在形参列表的最后。
    在调用函数时,主调函数的实参与被调函数的形参按从左至右的顺序进行匹配对应。
    例1-1 函数声明示例

    void defaultvalue1(int = 2, double = 3.0); //正确
    void defaultvalue2(int a, double b = 3.0); //正确
    void defaultvalue3(int a = 2, double b);  //错误
    void func1(int a, int b = 2,int c = 3);  //正确
    void func2(int a = 1, int b,int c = 3);  //错误
    void func3(int a = 1, int b = 2,int c);  //错误
    

    例1-2 函数调用示例(一)

    假设给出如下的函数声明
    void func(int a,int b =2,int c = 3);
    
    func(1,22,33);//正确
    func(); //错误,参数a没有默认值
    func(10,20);//正确
    func(5,,9);//错误,给出的实参必须是连续的。
    

    例1-3 函数调用示例(二)

    int Max(int m,int n);
    int a,b;
    void func2(int x,int y = Max(a,b),int z = a - b){...}
    
    func2(4);  //正确
    func2(4,9);  //正确
    

    五)、引用和函数参数的传递

    引用相当于给变量起了一个别名。同一个变量的引用可以有多个。引用的定义格式如下

    类型名 &引用名 = 同类型的某变量名;
    
    举例如下
    int oneInt;
    int &aname = oneInt;  //声明引用
    

    定义引用时需要进行初始化。
    定义引用时,可以在定义的前面加上cosnt关键字,表明该引用是“常引用”。例如:

    int oneInt;
    const int &cname = oneInt;
    

    常引用与普通引用区别在于:不能通过常引用去修改其引用的变量。
    例如,引用的定义与使用 程序1-4

    #include <iostream>
    using namespace std;
    int main()
    {
        int oneInt = 1;
        int &ref = oneInt;  //ref是oneInt的引用,ref等价于oneInt
        const int &refc = oneInt;   //定义常引用
        ref = 2;    //修改ref也即修改了oneInt
        cout<<"oneInt=" <<oneInt <<","<<"ref=" <<ref<<endl;//输出oneInt=2,ref=2
        cout<<"refc="<<refc<<endl;  // 输出refc=2
        oneInt = 3;     //修改oneInt也即修改了ref
        cout<<"ref="<<ref<<endl; 
        cout<<"refc="<<refc<<endl;
        int &ref2 = ref;        //ref2和ref都是oneInt的引用
        cout<<"ref2="<<ref2<<endl;
        //refc=5;   //错误,不能使用常引用对所引用的变量进行修改 
        return 0; 
    }
    
    image.png

    例如对引用进行初始化示例 程序1-5

    #include <iostream>
    using namespace std;
    int main()
    {
        const int cInt = 30;
        int oneInt = 50;
        int &ref = oneInt;  //T& ←T
        const int &rc1 = cInt;  //CT& ←CT,CT&表示类型T的常引用
        const int &rc2 = oneInt;    // CT& ←T
        const int &rc3 = ref;   //CT& ←T&
        int dInt = ref;         //T ←T&
        int eInt = cInt;    // T←CT,CT表示常量类型
        int fInt = rc1;     // T ←CT&
        const int gInt = oneInt;    //CT ←T
        int &ref1 = ref;    //T& ←T&
        const int hInt = ref;   //CT ←T&
        const int jInt = cInt;  //CT←CT
        const int &mInt = rc1; //CT& ←CT&
        const int nInt = rc2;   //CT ←CT&
        cout<<"OK"<<endl;
        int & r2 = (int &)rc1;  //t& ←CT&强制类型转换
        int & r3 = (int &)cInt; //t& ←CT强制类型转换
        return 0; 
        
    }
    

    T表示类型,CT表示常量类型,T&表示T类型的引用,CT&表示类型T的常引用。
    在C++中,函数调用时参数的传递有两种方式:传值传引用
    传值,是传递对象的值。传引用是传递对象的首地址值。

    程序1-6 不同的参数传递方式

    #include <iostream>
    using namespace std;
    void SwapValue(int a,int b)
    {
        int tmp;
        tmp = a;
        a = b;
        b = tmp;
        cout<<"在SwapValue()函数中:\t\ta="<<a<<",b="<<b<<endl;
        return;
    }
    void SwapRef(int &a,int &b)     //a,b值互换
    {
        int tmp;
        tmp = a;
        a = b;
        b = tmp;
        cout<<"在SwapRef()函数中:\t\ta="<<a<<",b="<<b<<endl;
        return;
     } 
    int main()
    {
        int a = 10,b = 20;
        cout<<"数据交换前:\t\ta="<<a<<",b="<<b<<endl<<endl;
        SwapValue(a,b);
        cout<<"调用SwapVal()后:\t\ta="<<a<<",b="<<b<<endl<<endl;
        a = 10;
        b = 20;
        SwapRef(a,b);
        cout<<"调用SwapRef()后:\t\ta="<<a<<",b="<<b<<endl<<endl;
        return 0;
    }
    
    
    数据交换前:            a=10,b=20
    
    在SwapValue()函数中:           a=20,b=10
    调用SwapVal()后:               a=10,b=20
    
    在SwapRef()函数中:             a=20,b=10
    调用SwapRef()后:               a=20,b=10
    

    返回引用的函数原型的格式如下

    数据类型 & 函数名(参数列表);
    

    程序1-7 引用作为函数返回值

    #include <iostream>
    using namespace std;
    int oneX = 10;
    int oneY = 20;
    int &refValue(int &x)
    {
        return x;
    }
    int main()
    {
        refValue(oneX) = 30;    //返回值是引用,可以作为左值使用
        cout<<"oneX="<<oneX<<endl;  //输出oneX=30;
        refValue(oneY) = 40;    //返回值是引用的函数调用表达式,可以作为左值使用
        cout<<"oneY="<<oneY<<endl;  //输出oneY=40
        return 0; 
    }
    

    函数的返回值还可以是指针,称为指针函数

    类型标识符 * 函数名(参数列表);
    

    六)、const与指针共同使用

    与C语言一样,C++语言也可以使用const限定访问权限,告诉编译器,它所修饰的量是不能改变的,也就是不能作为左值使用。
    使用指针时,涉及的量一个时指针本身;另一个时指针所指向的内容。

    const修饰指针变量时,基本含义如下:
    1)如果唯一的const位于符号的左侧,表示指针所指数据是常量,数据不能通过本指针改变,但可以通过其他方式进行修改;指针本身是变量,可以指向其他的内存单元。
    2)如果唯一的const位于符号
    的右侧,表示指针本身是常量,不能让该指针指向其他内存地址:指针所指的数据可以通过本指针进行修改。
    3)在符号*的左右各有一个const时,表示指针和指针所指数据都是常量,既不能让指针指向其他地址,也不能通过指针修改所指向的内容。

    程序1-8 常量说明示例

    #include <iostream>
    using namespace std;
    int main()
    {
        int a1 = 3; //普通变量,a1 = 5是正确的
        const int a2 = a1;  //数据是常量的,a2 = 5是错误的
        int *a3 = &a1;  //普通指针指向普通变量,*a3 = 6是正确的
        const int * a4 = &a1;   //数据是常量的,普通指针*a4=5是错误的
        int * const a5 = &a1;   //指针是常量的,不能修改指针,但*a5 = 10是正确的
        int const * const a6 = &a1; //数据是常量的,指针也是常量的
        const int * const a7 = &a1;  //数据是常量的,指针也是常量的
        return 0;
    }
    

    const的修饰规则:const修饰其左侧的内容;如果const是本行的第一个标识符,则它修饰其右侧的内容。

    七)、内联函数

    在C++语言中使用inline关键字来定义内联函数。inline放在函数定义中函数类型之前。

    inline 返回值类型 函数名(形参表)
    {
      函数体
    }
    

    内联函数主要应用于代码量较少的函数。
    循环语句和switch语句不能声明为内联函数。

    八)、函数的重载

    所谓函数重载,是指在程序的同一范围内声明几个功能类似的同名函数。
    例1-6 求两者中较大值的函数重载

    int bigger(int x,int y)
    {
        if(x>y)return x;
        else return y;
    }
    float bigger(float x,float y)
    {
        if(x>y)return x;
        else return y;
    }
    double bigger(double x,double y)
    {
        if(x>y)return x;
        else return y;
    }
    

    例1-7 求绝对值函数的重载

    int abs(int n)
    {
        return (n < 0?-n:n);
    }
    float abs(float n)
    {
        if(f<0)f=-f;
        return f;
    }
    double abs(double d)
    {
        if(d < 0)return -d;
        return d;
    }
    

    实现函数的重载必须满足下列条件之一

    1. 参数表中对应的参数类型不同
    2. 参数表中参数个数不同。
      例1-8 错误的重载函数
    float add(int,float);  //将整数和浮点数相加,返回浮点数
    int add(int,float);  //将整数和浮点数相加,返回整数,错误!
    

    例1-9 错误的重载函数

    void print(double);
    void print(double&);
    

    例1-10 调用重载函数

    int xI = 10,yI = 20;
    float xF = 30,yF = 40;
    double xD = 50,yD = 60;
    cout<<bigger(xI,yI)<<endl;
    cout<<bigger(xF,yF)<<endl;
    cout<<bigger(xD,yD)<<endl;
    

    例1-11 调用函数时进行必要的类型提升

    double bigger(double x,double y)
    {
        if(x>y)return x;
        else return y;
    }
    int xI = 10,yI = 20;
    float xF = 30,yF = 40;
    double xD = 50,yD = 60;
    cout<<bigger(xI,yF)<<endl;
    

    例1-12 调用重载函数时的二义性

    int Sum(int a,int b,int c=0);
    int Sum(int a,int b);
    调用语句
    Sum(1,2);
    

    九)、指针和动态内存分配

    指针变量中保存的是一个地址,有时也称指针指向一个地址。
    在C++语言中,使用new运算符实现动态内存分配。例如

    p = new T;
    

    T是任意类型名,p是类型为T*的指针。这种语句会动态分配除一片大小为sizeof(T)字节的内存空间。并将起始地址赋值给指针p。例如

    int *p;
    p = new int;
    *p = 5;
    

    使用new还可以动态分配一个任意大小的数组

    p = new T[N];
    

    例1-14 动态分配整形数组

    int *pArray;        //指向数组的指针
     int i = 5;         
     pArray = new int[i*20];    //分配了100个元素的整型数组
    pArray[0] = 20; //数组的第一个值
    pArray[99] = 30;    //数组的最后一个值 
    

    使用new运算符动态申请的内存空间,需要在使用完毕释放。使用delete运算符来释放动态分配的内存空间。

    delete 指针;
    

    例1-15 释放指针时出错

    int oneInt = 6;
    int *p = &oneInt;
    cout<<*p<<endl;
    delete p;   //出错,p是引用,不是动态分配的
    int *q = new int;
    *q = 8;
    cout<<*q<<endl;
    delete q;
    

    如果使用new动态分配了一个数组,释放时,

    delete []指针;
    

    十)、用string对象处理字符串

    专门用来处理字符串。
    string是一个类,这个类型的变量称为“string对象”。一个string对象的大小是固定的。
    要在程序中使用string大小,必须在程序中包含头文件string

    #include <string>
    

    1.声明string对象

    string 变量名;
    

    例如

    string str1;  //声明string对象str1,值为空
    string city = "Beijing";  // 声明string对象city,并使用字符串常量进行初始化
    string str2 = city;  //声明string对象str2,并使用字符串变量进行初始化
    cout<<"str1="<<str1<<"."<<endl;
    cout<<city<<","<<str2<<endl;
    

    还可以使用字符数组对string变量进行初始化

    char name[] = "C++程序";
    string s1 = name;
    
    string citys[] = {"Beijing","Shanghai","Tianjin","Chongqing"};
    cout<<citys[1]<<endl;   //输出Shanghai,数组下标从0开始 
    cout<<sizeof(citys)/sizeof(string)<<endl;   //输出数组元素个数 4
    

    2. string对象的操作

    可以使用cin和cout进行输入和输出。例如

    string s1,s2;
    cin>>s1>>s2;
    cout<<s1<<","<<s2<<endl; 
    

    string对象之间可以互相赋值,也可以用字符串常量和字符数组的名字对string对象进行赋值。例如

    string s1,s2 = "OK";
    s1 = "China";
    s2 = s1;    //s1和s2表示的字符串不等长,赋值后s2的内容和s1相同
    cout<<"s1="<<s1<<"      s2="<<s2<<endl; 
    

    例1-16 string的使用

    string s1,s2;
    s1 = "C++程序";
    s2 = s1;
    string s3;
    cout<<"s3="<<s3<<endl;  //输出s3=
    s3 = s1+s2;
    cout<<s1+s2<<endl; //输出C++程序C++程序
    cout<<"s3="<<s3<<endl;  //输出s3=C++程序C++程序
    s3 += "de";
    cout<<"s3="<<s3<<endl;  //输出s3=C++程序C++程序de
    
    bool b = s1<s3;     //b为true
    cout<<"bool="<<b<<endl;     //输出bool=1
    char c = s1[2]; //c为'+',
    cout<<"c="<<c<<endl;
    cout<<s1[2]<<endl;
    char arrstr[] = "Hello";
    s3 = s1 + arrstr;
    cout<<s3<<endl; //C++程序Hello
    

    3. string对象用法示例

    image.png

    例程序1-9 字符串成员函数的使用

    #include <iostream>
    #include <string.h>
    using namespace std;
    int main()
    {
        string str; //未初始化,空串
        if(str.empty())
            cout<<"str is NULL."<<",length="<<str.length()<<endl;
        else
            cout<<"str is not NULL."<<endl;
        str = str.append("abcdefg");
        cout<<"str is "<<str<<",size="<<str.size()<<endl;
        const char *p = str.c_str();
        cout<<"p="<<p<<endl;
        cout<<"find:"<<str.find("de",0)<<endl;      //查找成功,3
        cout<<"find:"<<str.find("de",4)<<endl;      //查找失败
        string str1 = str.insert(4,"123");
        cout<<str1<<endl;
        return 0; 
         
    }
    编译结果
    str is NULL.,length=0
    str is abcdefg,size=7
    p=abcdefg
    find:3
    find:18446744073709551615
    abcd123efg
    

    程序1-10 字符串成员函数的使用

    #include <iostream>
    #include <cstring>
    using namespace std;
    int main()
    {
        string s1 = "C++语言";
        string s2 = "程序设计";
        string s3 = s1+s2;
        string s4;
        s4 = s1.append(s2);
        if(s3 == s4) cout<<"结果相同"<<endl;
        else cout<<"结果不相同"<<endl;
        int size = s1.size();
        int length = s1.length();
        cout<<"size="<<size<<"  ,length="<<length<<endl;
        s1[0]='J';
        string s5 = s1.substr(3,4);
        char str[20];
        strcpy(str,s5.c_str());
        cout<<"str="<<str<<endl;
        cout<<"s1="<<s1<<",s2="<<s2<<endl;
        s1.swap(s2);
        cout<<"s1="<<s1<<",s2="<<s2<<endl;
        cout<<"str="<<str<<endl;
        cout<<"s2="<<s2<<endl;
        cout<<s2.find(str)<<endl;
        return 0;
    }
    
    编译结果:
    结果相同
    size=15 ,length=15
    str=语言
    s1=J++语言程序设计,s2=程序设计
    s1=程序设计,s2=J++语言程序设计
    str=语言
    s2=J++语言程序设计
    3
    

    三、C++语言的程序结构

    C++程序以".cpp"作为文件扩展名。程序中必须有且仅有一个主函数main(),这是程序执行的总入口。
    程序的结束通常是遇到以下两种情形之一

    1. 在主函数中遇到return语句
    2. 执行到主函数最后面的括号}。

    注释有两种
    1.从/开始,到/结束。
    2.从//开始。

    相关文章

      网友评论

          本文标题:C++语言简介

          本文链接:https://www.haomeiwen.com/subject/lkzzgrtx.html