C++对C的扩充

C++属于半面向过程半面向对象编程语言

面向过程程序设计(Procedural Programming)和面向对象程序设计(Object-Oriented Programming, OOP)是两种常见的编程范式,它们各有特点和适用场景。

1> 面向过程:

面向过程程序设计是一种编程范式,它侧重于编写一系列计算步骤或过程的代码,每个过程都可以完成特定的任务。在这种范式中,程序被视为一系列函数的集合,数据在函数之间传递。 主要特点包括: 结构化:程序被分解为可重用的函数或过程。 功能划分:每个函数负责一个具体的任务。 顺序执行:程序按照代码的顺序执行操作。 局部变量和全局变量:数据通过参数传递给函数,函数内部通常使用局部变量,也可以使用全局变量。 面向过程编程的典型语言包括C语言。

2> 面向对象:

面向对象程序设计是基于“对象”的概念,其中对象是数据和操作数据的方法的集合。这种范式强调将现实世界的实体作为对象进行模拟,每个对象都可以接收消息、处理数据和发送消息到其他对象。 主要特点包括: 封装:隐藏对象的内部状态和实现细节,只暴露有限的操作接口。 继承:允许新的对象类继承现有对象类的属性和方法。 多态性:允许不同类的对象对同一消息做出响应。 对象实例:程序定义为对象的集合,每个对象都可以具体实例化。 面向对象编程的典型语言包括Java、C++和Python。

3> 比较

维护性:面向对象程序设计通常更易于维护和扩展,因为它强调封装和模块化。 复用性:面向对象程序设计通过继承和多态提高代码复用性。 开发效率:面向对象程序设计在处理复杂系统时,可以更快地开发,因为它提供了更多高级抽象。

C++是对C的扩充

1> C++是对C语言的扩充,C语言的所有语法及函数,C++都能继续使用,并且在该基础上进行了扩充

2> C语言的编译器是gcc,而C++的编译器是g++,并且g++编译器比gcc编译器更加严格

3> C++程序的后缀一般为 .cpp .cxx .cc .C .hpp

4> C++中的头文件,一般不以.h结尾,C++中的头文件名,就是类名

5> C语言的头文件,在C++中依然可以使用,但是C++对C语言的头文件进行了二次封装

#include<stdio.h>      //在g++编译器中,如果没有加头文件,会直接报错

int main(int argc, const char *argv[])
{
    printf("hello a\n");

    int num = 520;          //定义一个普通整形变量
    void * vptr = &num;

    char * cptr = (char *)vptr;      //将万能指针转换为char*的指针,g++编译器要求必须强转
    
    return 0;
}

第一个C++程序框架解析

#include <iostream>
//#:表示这是一条预处理指令
//include:表示这是一条文件包含指令
//<>:表示直接使用的是系统库中的文件
//i:input    o:output     stream:   引入的是输入输出流的头文件
//iostream:是由istream和ostream共同产生的一个用于进行io操作的类


using namespace std;
//这是一条命名空间的声明语句
//using:是使用命名空间的关键字
//namespace:是命名空间的关键字
//std:标准命名空间,系统提供的所有的名字,都会放入到该命名空间中




int main()          //提供的是无参的主程序,也就是不需要外部传参
{
    cout << "Hello World!" << endl << 520 << 1314<<'\t'<<3.14;
    cout<<"hello world";
    cout<<endl;
    //使用iostream中的类对象cout输出数据hello world    类似于 printf
    //<< :插入运算符,是一个运算符,不是左移运算,是C++重载的运算符,跟cout搭配用于输出,类似于 printf后的括号
    //"Hello World!" :原样输出的内容
    //第二个尖括号,表示再次输出内容
    //endl: end line  :换行,类似于C语言的 '\n'
    //cout:会自动识别要输出的数据类型并输出


    return 0;
}

3.1 输出操作

1> 在C++中,向终端输出数据,使用的是ostream提供的一个类对象(结构体变量) cout,搭配插入运算符(

2> cout输出数据时,不需要使用格式控制符,会自动识别要输出的数据的数据类型

3> cout输出数据时,可以级联输出数据,级联输出时,需要使用多个插入运算符

#include <iostream>

using namespace std;

int main()
{
    cout << "Hello World!" << endl;      //输出一个字符串

    int numb = 24101;
    char Class[20] = "班级";
    double score = 88.8;
    cout << numb <<endl;            //输出一个整数
    cout << Class <<endl;            //输出一个字符数组
    cout << score <<endl;              //输出一个实数


    return 0;
}
#include <iostream>

using namespace std;

int main()
{
    int a[20];          //用于存储20项数据

    for(int i=0;i<20;i++)       //循环给数组的每个元素赋值
    {
        if(i<2)               //前两项数据全为1
        {
            a[i] = 1;
        }else
        {
            a[i] = a[i-2] + a[i-1];        //从第三项开始,每一项等于前两项的和
        }
    }

    cout<<"斐波那契数列前20项分别是:";
    for(int i=0; i<20; i++)
    {
        cout<<a[i]<<'\t';
    }
    cout<<endl;
}
#include <iostream>
#include<iomanip>           //有关格式化输出函数的头文件

using namespace std;

int main()
{
    int num = 1010;

    cout<< "num = " << num <<endl;          //默认输出的是十进制数据 1010

    /********************使用关键字设置进制数的输出**************************/
    cout<< oct <<"num = " << num <<endl;        //输出的就是八进制数据  1762
    cout<< "num = " << num <<endl;             //后面输出的数据都是八进制数
    cout<< hex <<"num = " << num <<endl;           //输出的是十六进制数据 3f2
    cout<< "num = " << num <<endl;             //后面输出的数据都是十六进制数
    cout<< dec <<"num = " << num <<endl;             //后面输出的数据都是十进制数

    /************************使用函数完成进制数的输出***********************/
    cout<<"*******************************************************\n";
    cout<< setbase(8) <<"num = " << num <<endl;           //输出八进制数据 1762
    cout<< "num = " << num <<endl;             //后面输出的数据都是八进制数
    cout<< setbase(16) <<"num = " << num <<endl;           //输出十六进制数据 3f2
    cout<< setbase(10) <<"num = " << num <<endl;           //输出十进制数据 1010
    cout<< setbase(7) <<"num = " << num <<endl;           //设置其他进制默认是十进制

    cout<<"*******************************************************\n";
    /************************printf("%-10d", 520);***********************/
    cout <<"num = " << setw(10)<< right <<num <<endl;        //至少提供10个位置,用于数据输出,右对齐
    cout <<"num = " << setw(10)<< left << num <<endl;  ////至少提供10个位置,用于数据输出,左对齐


    cout<<"*******************************************************\n";
    /***************************输出小数**********************************/
    double PI = 31.4159265358;
    cout<<"PI = "<<PI<<endl;                  //默认保留6位有效数字,如果超过,则使用科学计数法
    cout<< setprecision(10) <<"PI = "<<PI<<endl;    //保留10个有效数字
    cout<< fixed <<setprecision(2) <<"PI = "<<PI<<endl;     //保留两位小数 setprecision和fixed表示保留小数点后n位

    return 0;
}

1> C++中的输入使用的是istream提供的一个类对象 cin, 并结合提取运算符 (>>)一起使用,用作数据的输入

2> cin进行输入时,也无需使用格式控制符,系统直接自动识别数据类型并输入

3> 输入数据时吗,一般也不使用endl

#include <iostream>

using namespace std;

int main()
{
    int num = 0;        //整形数据
    cout<<"请输入num的值:";
    cin >> num;              //输入整形数据
    cout <<"num = "<<num<<endl;        //

    cout<<"********************************\n";
    char key = 0;        //字符数据
    cout<<"请输入key的值:";
    cin >> key;              //输入字符数据
    cout <<"key = "<<key<<endl;        //

    cout<<"********************************\n";
    char name[20] = "";        //字符串数据
    cout<<"请输入name的值:";
    cin >> name;              //输入字符串数据
    cout <<"name = "<<name<<endl;        //

    cout << "Hello World!" << endl;
    return 0;
}

练习:提示并输入一个字符,如果是大写转变成小写,如果是小写转变成大写,如果是其他字符,都转变成 * ,输出转变后的数据

要求使用cin和cout完成

#include <iostream>

using namespace std;

int main()
{
    char n;            //定义变量存储数据
    cout<<"请输入一个字符:";
    cin>>n;                  //输入一个字符数据
    if (n>='A'&&n<='Z')         //判断大写字母
    {
        n=n+32;         //将大写转变成小写
        //cout << n+32 << endl;         //输出的是整数
    }
    else if(n>='a'&& n<='z')
    {
        n=n-32;               //小写转大写
    }else
    {
        n = '*';
    }

    cout<<"n = "<<n<<endl;          //输出结果

    return 0;
}

4.2 使用系统提供的命名空间

1> 连名带性一起使用,但是,需要在名字前面加上命名空间名和作用域限定符(::)

2> 将命名空间中的某个名字,做提前声明,后期使用该名字时可以直接用,不需要加命名空间名和作用域限定符

3> 将整个命名空间进行前置声明,后面使用该命名空间中的任意一个名字都无需加命名空间名和作用域限定符了

#include <iostream>        //该头文件中,提供了std命名空间的定义,但是,当使用名字时,需要进行声明

int main()
{

    //命名空间使用 方式1:连名带性一起使用
    std::cout << "hello a" << std::endl;

    //命名空间使用方式2:将命名空间中某个名字进行前置声明
    using std::cout;             //表示将命名空间std中的cout声明一下
    cout << "你好" << std::endl;         //此时cout可以使用,因为前置声明了,但是endl不能使用,因为没有声明

    //命名空间的使用方式3:将整个命名空间全部进行声明
    using namespace std;          //将std整个命名空间全部声明
    cout<<"愿世界和平"<<endl;

    return 0;
}

4.4 命名空间中的名字冲突问题

1> 不同的命名空间中的名字冲突时,如果两个吗,命名空间全部进行整体声明了,那么需要在使用冲突的名字前加命名空间名和作用域限定符用于区分。

2> 命名空间中的名字与全局变量(匿名空间)名字冲突,也要使用命名空间名和作用域限定符进行区分,匿名空间中的名字使用方式为 ::名字

3> 命名空间中的名字和局部变量的名字冲突,优先使用局部变量,如果非要使用命名空间中的名字,需要加上命名空间名和作用域限定符

#include <iostream>
#include<string.h>

using namespace std;

//自定义张三的命名空间
namespace zhangs
{
    int num = 520;
    char name[20] = "";
}

//自定义李四的命名空间
namespace lisi
{
    int num = 1314;
    double score = 99.5;
}

//将两个命名空间都进行声明
using namespace zhangs;
using namespace lisi;

float score = 33.33;           //定义全局变量   全局变量中的名字,会默认放入的匿名空间中


int main()
{
    //命名空间中的名字和匿名空间中的名字冲突
    lisi::score = 100;          //使用的是李四命名空间中的名字
    ::score = 66.66;            //此时使用的是全局变量(匿名空间中的名字)

    strcpy(name, "张三");     //使用的是张三命名空间中的名字

    //不同命名空间中的名字冲突
    zhangs::num = 666;          //冲突, 需要加上命名空间名和作用域限定符
    lisi::num = 999;             //使用的是李四命名空间中的名字


    //当局部变量和命名空间中的名字冲突时,优先使用局部变量
    int name = 1111;

    cout<<"name = "<<name<<endl;          //使用的是局部变量
    cout<<"name = "<<zhangs::name<<endl;         //使用的是命名空间中的名字


    return 0;
}

C++中支持的字符串

#include <iostream>

using namespace std;

int main()
{
    //1、定义一个字符串变量 :如果不初始化,则该字符串是一个空串
    string s1;                           // 无参构造函数
    cout<<"s1 = "<< s1 <<endl;          // 是一个空串

    //2、定义一个字符串变量,并初始化
    string s2 = "hello a";               //拷贝构造函数
    cout<<"s2 = "<<s2<<endl;            //hello a

    //3、定义一个字符串并初始化
    string s3 = {"hello world"};
    cout<<"s3 = "<<s3<<endl;               //hello world

    //4、定义一个字符串并初始化
    string s4("你 好");               //有参构造函数
    cout<<"s4 = "<<s4<<endl;           //你 好

    //5、定义一个字符串并初始化
    string s5(5, 'A');                  //有参构造函数
    cout<<"s5 = "<<s5<<endl;             //AAAAA

    //6、对字符串变量的赋值
    s1 = "逆天了";        //拷贝赋值函数        //C++风格 的字符串的赋值,不需要使用strcpy完成可以直接使用赋值运算符
    cout<<"s1 = "<<s1<<endl;           //逆天了

    return 0;
}
2>    多个变量的初始化及赋值
#include <iostream>

using namespace std;

int main()
{
    string s1 = "hello a";      //定义一个字符串变量并初始化

    //定义一个字符串变量,并使用另一个字符串给其进行初始化
    string s2 = s1;
    cout<<"s2 = "<<s2<<endl;         //hello a

    //定义一个字符串变量,使用另一个字符串给其进行初始化
    string s3(s2);
    cout<<"s3 = "<<s3<<endl;          //hello a

    //定义一个字符串变量,使用另一个字符串变量给其进行初始化
    string s4 = {s1};
    cout <<"s4 = " << s4<<endl;       //hello a

    //定义一个字符串使用另一个字符串给其进行赋值
    string s5;
    s5 = s1;                   //不需要使用strcpy,直接使用赋值运算符完成两个字符串变量的赋值
    cout<<"s5 = "<<s5<<endl;     //hello a

    //定义一个字符串,使用两个字符串连接后的结果进行初始化
    string s6 = s1+s2;            //s1+s2表示将s2连接到s1后面  取代了strcat的功能
    cout<<"s6 = "<<s6<<endl;         //hello ahello a

    //定义一个字符串使用一个字符串变量与一个字符串常量拼接后的结果初始化
    string s7 = s1 + " 世界";
    cout<<"s7 = "<<s7<<endl;          //hello a 世界

    // 定义一个字符数,使用一个字符串常量和一个字符串变量拼接后的结果初始化
    string s8 = "滴滴滴 " + s1;
    cout<<"s8 = "<<s8<<endl;            //滴滴滴 hello a
    
    //string s9 = "hello " + "world";            //两个字符串常量是不能进行加法运算


    return 0;
}

多个变量的初始化及赋值

#include <iostream>
#include<cstring>            //#include<string.h>

using namespace std;

int main()
{
    char str[20] = "hello a";        //C语言风格的字符串

    string s1 = str;                //c风格的字符串可以直接转换为C++风格的字符串
    cout<<"str = "<<str<<endl;       //hello a
    cout<<"s1 = "<<s1<<endl;         //hello a

    s1 = "24101班";             //C++风格字符串的赋值


    //将C++风格的字符串转变成C语言风格的字符串需要调用成员函数 : data()  或者  c_str()
    strcpy(str, s1.c_str());//str = s1;            //不可以,不能将C++风格字符串直接转换为C风格字符串
    strcpy(str, s1.data());
    //s1是C++风格的字符串, 可以通过s1.c_str()或者s1.data() 找到s1对应的C风格字符串

    cout<<"str = "<<str<<endl;       //24101班
    cout<<"s1 = "<<s1<<endl;         //24101班

    return 0;
}

 C++风格的字符串的比较

1> C风格的字符串的比较不能使用关系运算符,只能使用strcmp来完成

2> C++风格的字符串可以直接使用关系运算符完成字符串的比较

#include <iostream>
#include<cstring>

using namespace std;

int main()
{
    string s1 = "hello";
    string s2 = "world";

    //C++风格的字符串的比较可以直接使用关系运算符来完成  不需要使用strcmp
    if(s1>s2)
    {
        cout<<s1<<"大"<<endl;
    }else if(s1 < s2)
    {
        cout<<s2<<"大"<<endl;
    }else
    {
        cout<<"一样大"<<endl;
    }
    
    strcmp(s1.data(), s2.data());          //如果非要使用strcmp,需要转换成c风格的字符串进行比较

    return 0;
}

string类型常用的成员函数

1> size()或者length():求该字符串的实际长度

2> 访问字符串的成员

1、使用成员函数 at() 完成,会进行下标越界检查

2、使用中括号运算符完成,不进行下标越界检查

3> 判空:empty(),如果字符串为空,则返回真,否则返回假

4> 清空:clear() 将当前字符串清空

5> 尾插:push_back() 在字符串尾部插入一个字符

尾删:pop_back() 删除字符串尾部的那个字符

#include <iostream>

using namespace std;

int main()
{
   string s1 = "I love China";

   //求该字符串的实际长度
   cout<<"sizeof(s1) = "<<sizeof (s1)<<endl;          //求变量的空间大小   32
   cout<<"size of s1 = "<<s1.size()<<endl;           //求字符串实际长度    12
   cout<<"size of s1 = "<<s1.length()<<endl;           //求字符串实际长度    12

   //更改字符串中的某个字符
   s1[2] = 'L';                 //使用下标运算符,是不进行下标越界检查的
   cout<<"s1 = "<<s1<<endl;             //I Love China

   s1.at(2) = 'B';          //使用成员函数获取字符串中某个字符   是对字符串进行下标越界检查
   cout<<"s1 = "<<s1<<endl;             //I Bove China

   //判断当前字符串是否为空
   if(s1.empty())
   {
       cout<<"s1字符串为空"<<endl;
   }else
   {
       cout<<"s1字符串非空"<<endl;
   }

   //清空当前字符串
   s1.clear();
   //判断当前字符串是否为空
   if(s1.empty())
   {
       cout<<"s1字符串为空"<<endl;
   }else
   {
       cout<<"s1字符串非空"<<endl;
   }

   cout<<"s1 = "<<s1<<endl;            //空串

   //对字符串进行尾插
   s1.push_back('A');
   s1.push_back('B');
   s1.push_back('C');
   cout<<"s1 = "<<s1<<endl;             //ABC

   //对字符串进行尾删
   s1.pop_back();
   cout<<"s1 = "<<s1<<endl;             //AB
   
    return 0;
}

1> 不带空格的输入:可以直接使用cin完成

2> 带空格的输入: 使用全局函数 getline()来完成

#include <iostream>

using namespace std;

int main()
{
    string s1;            //定义一个字符串变量

    /*
    cout<<"请输入一个字符串:";
    cin >> s1;                  //输入不带空格的字符串
    cout<<"s1 = "<<s1<<endl;
    */

    cout<<"请输入一个字符串:";
    getline(cin, s1);               //既可以输入有空格的字符串,也可以输入没有空格的字符串
    cout<<"s1 = "<<s1<<endl;

    return 0;
}

bool类型

1> C语言是不支持bool类型的,但是C++支持bool类型

2> bool类型属于C++的基本数据类型

3> bool类型的数据的值只有两个:true(非0数字)、false(0)

4> 由于bool类型的出现,给C++的关键字多个三个,bool、true、false

5> bool类型的数据有两种表示方式,默认使用的是数字表示真假,所有非0数字都表示真,0表示假

如果想要使用单词(true、false)表示真假,则需要使用关键字boolalpha来设置

如果还想继续使用数字表示真假,则需要使用关键字noboolalpha来设置

6> bool类型所占内存大小:本质上只需要 1bit ,但是由于内存分配的基本单位是字节,所有bool类型占1字节内存

#include <iostream>

using namespace std;

int main()
{
    //bool类型的 数据默认使用数字表示真假
    bool b1 = 10;            //定义一个bool类型的变量并初始化
    cout<<"b1 = "<<b1<<endl;            // 1
    bool b2 = -10;
    cout<<"b2 = "<<b2<<endl;            // 1
    bool b3 = 0;
    cout<<"b3 = "<<b3<<endl;            // 0

    //使用单词表示真假
    cout<<"*************************************\n";
    cout<<boolalpha<<"b1 = "<<b1<<endl;            // true
    cout<<"b2 = "<<b2<<endl;            // true
    cout<<"b3 = "<<b3<<endl;            // false

    //继续使用数字表示
    cout<<"*************************************\n";
    cout<<noboolalpha<<"b1 = "<<b1<<endl;            // 1
    cout<<"b2 = "<<b2<<endl;            // 1
    cout<<"b3 = "<<b3<<endl;            // 0

    cout<<"*************************************\n";
    bool b4 = true;
    cout<<"b4 = "<<b4<<endl;              //1
    bool b5 = false;
    cout<<"b5 = "<<b5<<endl;              //0

    cout<<"*************************************\n";
    cout<<"sizeof(bool) = "<<sizeof (bool)<<endl;         //1

    return 0;
}

7.1 引入 new/delete

1> C语言中,对堆区空间的使用,由函数malloc\free来完成

2> C++中也可以用上面的两个函数完成对堆区空间的使用,但是C++提供了专门的两个关键字用于对堆区空间的使用

new / delete

7.2 new和delete的使用

1> C++中的堆区空间的使用分为单个空间的申请和释放以及连续空间的申请和释放

2> 单个空间的申请和释放

申请格式:数据类型 *指针名 = new 数据类型;

释放格式:delete 指针名;

#include <iostream>

using namespace std;

int main()
{
    //在堆区空间申请一个int类型的空间大小
    int *p1 = new int;            //如果没有初始化,默认是随机值
    cout<<"*p1 = "<<*p1<<endl;       //随机值

    *p1 = 520;             //使用堆区空间
    cout<<"*p1 = "<<*p1<<endl;          //520

    //在堆区申请一个double类型的空间并初始化
    double *dptr = new double(99.99);
    cout<<"*dptr = "<<*dptr<<endl;            //99.99


    //在堆区申请空间并初始化
    char *cptr = new char{'G'};
    cout<<"*cptr = "<<*cptr<<endl;

    // 释放堆区空间
    delete p1;
    p1 = NULL;            //防止野指针
    delete dptr;
    dptr = NULL;
    delete cptr;
    cptr = NULL;


    return 0;
}

3> 连续内存的申请和释放

申请格式:数据类型 *指针名 = new 数据类型[申请的个数];

释放格式:delete []指针名;

#include <iostream>

using namespace std;

int main()
{
    //在堆区连续申请5个int类型的空间
    int *iptr = new int[5];            //iptr[0]、。。。、iptr[4]
    for(int i=0; i<5; i++)
    {
        cout<<iptr[i]<<" ";
    }
    cout<<endl;


    //在堆区申请连续的存储空间并初始化
    double *dptr = new double[3]{3.14,5.67,99.99};
    for(int i=0; i<3; i++)
    {
        cout<<dptr[i]<<" ";
    }
    cout<<endl;

    //释放堆区空间
    delete []iptr;
    iptr = NULL;
    delete []dptr;
    dptr = NULL;


    return 0;
}

练习:要求在堆区连续申请5个int的大小空间用于存储5名学生的成绩,分别完成空间的申请、成绩的录入、升序排序、成绩输出函数以及空间释放函数,并在主程序中完成测试

#include <iostream>

using namespace std;

int main()
{
    int *iptr = new int[5];
    for(int i=0;i<5;i++)
    {
        int socre;
        cout<<"请输入同学的成绩:";
        cin>>socre;
        iptr[i] =socre;
    }
    for(int i=1;i<5;i++)
    {
        for(int j=0;j<5-i;j++)
        {
            if(iptr[j]>iptr[j+1])
            {
            int temp = iptr[j];
            iptr[j]= iptr[j+1];
            iptr[j+1] =temp;
             }
        }

    }
    for(int k=0;k<5;k++)
    {
        cout<<iptr[k]<<endl;

    }
    delete []iptr;
    iptr = NULL;
    return 0;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值