01-c++对c的扩展(上)

一、c++概况

1.c++编程思想

c++的编程思想:面向对象编程、泛型编程。

  • 面向对象:将数据和方法封装在一起,形成一个独立的对象,来实现某些特定的功能。C语言是面向过程的编程,是由一个个函数组成的,但函数只封装了功能没封装数据。面向对象则是由一个个对象组成一个完整的项目。

  • 泛型编程:主要体现在模板化,一个函数可以处理多种数据类型。

2.面向对象的三大特征

2.1面向过程与面向对象

  1. 面向过程是C语言的编程思想:先分析项目的实现步骤,然后通过函数实现一个个步骤,最后逐个调用这些函数实现完整的项目;
  2. 面向对象:即将方法和数据封装为一个对象,通过一个个对象来实现完整的项目。

2.2三大特征

  • c++的三大特性:封装、继承、多态
    1. 封装:将数据和方法封装在一起,并加以权限区分。一般数据私有,方法公有,外界可以通过公有方法操作私有数据;
    2. 继承:是类和类之间的父子关系,比如 B 类继承于 A 类,那么 B 类就拥有了 A 类的方法和属性,同时 B 类还能扩展自己的方法和属性;
    3. 多态:一个函数接口,多种方法,可以理解为,调用同一个函数,可以实现不同的功能。

3.第一个c++程序

  • 代码演示
c++ 复制代码
#include <iostream> // 头文件包含

using namespace std; // 使用命名空间

int main() {
    // std::cout << "Hello World!" << std::endl;
    cout << "hello world!" <<endl; // c++的输出函数

    int num1, num2;
    cin >> num1 >> num2; // 输入函数
    cout << "num1 = " << num1 << ", num2 = " << num2 << endl;
    return 0;
}
  • 运行结果

    hello world!
    100 200
    num1 = 100, num2 = 200

  • 说明:

    1. c++的官方头文件没有 .h ;
    2. iostream 是标准输入输出流,所有输入输出都来自于这个头文件;
    3. 第一种打印方法是指明 coutendl来自于 std ,如果这样写比较麻烦,就需要用到命名空间using namespace std 先声明,然后就可以简化成第二种写法了;
    4. cout 代表输出设备,endl 表示换行,cin 表示输入设备,输入数据时,不同数据用空格隔开;
    5. << 和 >> 代表输出输入的流向,方向不能搞反了。

二、c++对c的扩展

1.作用域运算符

::两个冒号就是作用域运算符,它描述的是归属问题,如前面代码std::cout中描述的就是cout属于std

  • 代码演示
c++ 复制代码
// 定义全局变量
int num = 10;
void test01()
{
    // 定义局部变量
    int num = 20;
    cout << "局部变量num = " << num <<endl;
    cout << "全局变量num = " << ::num <<endl;
}
  • 运行结果

    局部变量num = 20
    全局变量num = 10

  • 这里是作用域运算符的一个特殊用法,在正常情况,局部变量和全局变量同名的时候,遵循就近原则,但这里可以通过作用域运算符,让其在局部作用域优先使用全局变量。

2.命名空间

2.1命名空间概述

命名空间:命名空间的本质是为了防止命名冲突,给符号常量、变量、函数、结构体、枚举、类和对象加一个外壳。如两个相同名字的变量 num ,DATA::num 和 NUM::num 是不一样的。

2.2命名空间的定义

  • 代码演示
c++ 复制代码
// 定义一个命名空间
namespace AA
{
    int num = 100;
    void func()
    {
        cout << "这是命名空间AA里的func函数!" << endl;
    }
}

void test02()
{
    cout << "num = " << AA::num << endl;
    AA::func();
}
  • 运行结果

    num = 100
    这是命名空间AA里的func函数!

  • 说明:

    1. 命名空间只能在全局范围内定义;
    2. 命名空间里面的成员可以是普通变量,也可以是函数,或其它类型。

2.3命名空间的嵌套

  • 代码演示
c++ 复制代码
// 定义一个嵌套命名空间
namespace A
{
    int num1 = 10;
    namespace B
    {
        int num2 = 20;
    }
}

void test03()
{
    cout << "num1 = " << A::num1 << endl;
    cout << "num2 = " << A::B::num2 << endl;
}
  • 运行结果

    num1 = 10
    num2 = 20

  • 说明:命名空间的嵌套,只要一直访问到最底层就能取出数据。

2.4命名空间的开放性

所谓命名空间的开放性就是已经定义好的命名空间,后面还能给它添加新的成员。

  • 代码演示
c++ 复制代码
// 定义命名空间
namespace BB
{
    int num1 = 10;
}
// 给命名空间添加变量
namespace BB
{
    int num2 = 20;
}
// 给命名空间添加函数
namespace BB
{
    void func()
    {
        cout << "这是命名空间新追加的函数" << endl;
    }
}

void test04()
{
    cout << "num1 = " << BB::num1 << endl;
    cout << "num2 = " << BB::num2 << endl;
    BB::func();
}
  • 运行结果

    num1 = 10
    num2 = 20
    这是命名空间新追加的函数

2.5命名空间的声明和实现分离

声明和实现分离主要是针对命名空间的成员函数而言的。

  • 代码演示
c++ 复制代码
// 定义命名空间
namespace C
{
    void func1();
    void func2();
}

void C::func1()
{
    cout << "func1被执行" << endl;
}

void C::func2()
{
    cout << "func2被执行" << endl;
}

void test05()
{
    C::func1();
    C::func2();
}
  • 运行结果

    func1被执行
    func2被执行

  • 说明;

    1. 声明和实现分离,指函数在命名空间内声明,在命名空间外定义;
    2. 但函数定义的时候还是得在函数名前面加上作用域限制。

2.6无名命名空间

无名命名空间指在定义命名空间的时候没有名字,意味着命名空间中的标识符只能在本文件内访问,相当于给这个标识符加上了 static,使得其可以作为内部连接。

  • 代码演示
c++ 复制代码
// 定义命名空间
namespace
{
    int a = 10;
    int b = 20;
}

void test06()
{
    cout << "a = " << ::a << endl;
    cout << "b = " << ::b << endl;
}
  • 运行结果

    a = 10
    b = 20

  • 说明:无名命名空间的访问和全局变量的访问一样,在c++里面全局变量是内部连接,与C语言外部连接不同,它只能在当前文件可用。

2.7命名空间取别名

语法:namespace 别名=原名字

  • 代码演示
c 复制代码
namespace longName
{
    int a = 11;
    int b = 22;
}

void test07()
{
    namespace newNAME = longName; // 起别名
    cout << "a = " << newNAME::a << endl;
    cout << "b = " << newNAME::b << endl;
}
  • 运行结果

    a = 11
    b = 22

2.8using 声明

2.8.1using 声明某个成员

我们使用命名空间::成员访问绝对麻烦的时候,可用通过using声明一下。

  • 代码演示
c++ 复制代码
namespace D
{
    int a = 10;
    int b = 20;
    int c = 30;
}
using D::b;
using D::c;

// int c = 35;

void test09()
{
    cout << "a = " << D::a << endl;
    cout << "b = " << b << endl;
    int b = 25;
    cout << "局部变量b = " << b << endl;
    //cout << "c = " << c << endl;
}
  • 运行结果

    a = 10
    b = 20
    局部变量b = 25

  • 说明:

    1. 当声明的命名空间成员和局部变量同名时,局部变量优先级高;
    2. 当声明的命名空间和全局变量同名时,两者没有优先级的概念,命名冲突会报错。
2.8.2using 声明遇到函数重载
  • 代码演示
c++ 复制代码
namespace E
{
    void func(void)
    {
        cout << "无参的函数func执行" << endl;
    }
    void func(int a)
    {
        cout << "一个参的函数func执行" << endl;
    }
    void func(int a, int b)
    {
        cout << "两个参的函数func执行" << endl;
    }
}
using E::func;

void test10()
{
    func();
    func(1);
    func(2, 3);
}
  • 运行结果

    无参的函数func执行
    一个参的函数func执行
    两个参的函数func执行

  • 说明:

    1. 函数重载:在同一作用域中,函数名相同,函数的参数的个数、类型、顺序不相同都是函数重载。同一函数,传入的参数个数、类型、顺序不同,执行的功能就不相同。和C语言不一样,C语言通过函数名区分不同函数,c++通过函数名和参数共同区分不同函数;
    2. using 声明的时候,声明的是函数名,因此声明一次,相当于声明了所有同名函数,然后调用的时候就可以根据传入参数不同执行不同功能,这是c++里面的动态多态。
2.8.3声明整个命名空间

我们在前面代码中:using namespace std;就是声明整个命名空间。

  • 代码演示
c++ 复制代码
namespace F
{
    int a = 10;
    int b = 20;
    int c = 30;
}
using namespace F; // 声明整个命名空间
// int c = 40;

void test11()
{
    cout << "a = " << a << endl;
    cout << "a = " << b << endl;
    cout << "a = " << c << endl;
}
  • 运行结果

    a = 10
    a = 20
    a = 30

  • 说明:

    1. 声明整个命名空间,即命名空间的所有成员不通过命名空间::成员的方法都能访问;
    2. 当要注意全局变量不能和命名空间的成员冲突,否则会报错。

三、c++常见数据类型增强

1.声明增强

  • 代码演示
c++ 复制代码
// 声明全局变量和函数
extern int num1;
extern void func();

void test12()
{
    cout << "num1 = " << num1 << endl;
    func();
}

int num1 = 100;
void func()
{
    cout << "函数func执行" << endl;
}
  • 运行结果

    num1 = 100
    函数func执行

  • 说明:

    1. 在C语言里,同一个文件里,变量和函数的声明可以不加 extern 也能声明;
    2. 在c++里,即使是同一个文件里,变量和函数的声明必须加 extern。

2.函数参数增强

  1. 在C语言中,定义函数的时候,函数形参可以不写数据类型也能定义,但是c++的函数形参必须指明形参的数据类型;
  2. C语言中,定义函数的时候即使没有形参,在调用的时候也可以传参,不会有什么影响,只是传的参数没用罢了;但是c++传参的个数和类型必须和定义的时候保持一致,和前面提到的函数重载可以关联起来,因为即使函数名相同,传入的参数的个数、顺序、类型不同,会执行不同的功能。

3.结构体类型增强

3.1 c++定义结构体变量

C语言中定义结构体变量的时候必须加 struct ,但c++中可以不加。

  • 代码演示
c++ 复制代码
// 定义一个结构体
struct stu
{
    int num;
    char name[32];
};

void test13()
{
    // C语言中必须加stuct
    // struct stu obj = {101, "jack"};
    // c++ 中可以省略
    stu obj = {101, "jack"};
    cout << "num = " << obj.num << ", name = " << obj.name << endl;
}
  • 运行结果

    num = 101, name = jack

3.2 c++结构体中定义函数

  • 代码演示
c++ 复制代码
struct stu
{
    int num;
    char name[32];
    void func()
    {
        cout << "我的学号是:" << num << ",我的名字叫:" << name << endl;
    }
};

void test13()
{
    stu jack = {101, "jack"};
    stu rose = {102, "rose"};
    jack.func();
    rose.func();
}
  • 代码演示

    我的学号是:101,我的名字叫:jack
    我的学号是:102,我的名字叫:rose

  • 说明:

    1. c++ 的结构体中可以直接定义函数;
    2. 当我们定义两个结构体变量的时候,就开辟了两份空间分别存储两个变量的数据,但是方法是共用的,不管定义多少个结构体变量,方法都只有一份,调用的时候结构体变量.函数名(),告诉系统是哪个结构体变量调用函数,就用哪个变量的数据执行函数。

4.bool 类型

bool 类型定义的变量只能赋值: true 真, false 假(赋其他值也不一定报错,但不建议,也无意义)。

  • 代码演示
c++ 复制代码
// 定义一个bool类型变量
bool flag = true;

void test14()
{
    int i = 1;
    while (flag)
    {
        cout << "i = " << i << endl;
        if (i == 5)
            flag = false;
        i++;
    }
}
  • 运行结果

    i = 1
    i = 2
    i = 3
    i = 4
    i = 5

  • 说明:bool 类型一般结合循环语句和条件语句来使用。

5.三目运算符增强

  • 代码演示
c++ 复制代码
void test15() {
    int a = 10;
    int b = 20;
    // C语言c++都支持的写法
    int ret = a > b ? a : b;
    cout << "ret = " << ret << endl;

    // C语言不支持,c++支持
    a > b ? a : b = 100;
    cout << "b = " << b << endl;
}
  • 运行结果

    ret = 20
    b = 100

  • 说明:

    1. C语言中,三目运算符返回的是符合条件的变量的值,给值赋值肯定不行,会报错;
    2. c++中返回的是符合条件的变量的引用,是个变量,因此可以对其返回值赋值。
相关推荐
讨厌下雨的天空3 小时前
C++之list
开发语言·c++·list
Icomi_4 小时前
【神经网络】0.深度学习基础:解锁深度学习,重塑未来的智能新引擎
c语言·c++·人工智能·python·深度学习·神经网络
不知道取啥耶5 小时前
C++ 滑动窗口
数据结构·c++·算法·leetcode
zephyr_zeng6 小时前
VsCode + EIDE + OpenOCD + STM32(野火DAP) 开发环境配置
c语言·c++·vscode·stm32·单片机·嵌入式硬件·编辑器
Stack Overflow?Tan907 小时前
c++实现在同一台主机两个程序实现实时通信
开发语言·c++
@@永恒8 小时前
map&set
c++
小鹏编程8 小时前
【C++教程】C++中的基本数据类型
开发语言·c++·教程·少儿编程
熊峰峰8 小时前
C++第十节:map和set的介绍与使用
开发语言·c++
Antonio9158 小时前
【网络编程】事件选择模型
网络·c++
程序员Linc9 小时前
用OpenCV写个视频播放器可还行?(C++版)
c++·opencv·音视频·opencv 4.11