当前位置: 首页 > article >正文

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++程序

  • 代码演示
#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

  • 代码演示
// 定义全局变量
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命名空间的定义

  • 代码演示
// 定义一个命名空间
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命名空间的嵌套

  • 代码演示
// 定义一个嵌套命名空间
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命名空间的开放性

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

  • 代码演示
// 定义命名空间
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命名空间的声明和实现分离

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

  • 代码演示
// 定义命名空间
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,使得其可以作为内部连接。

  • 代码演示
// 定义命名空间
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 别名=原名字

  • 代码演示
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声明一下。

  • 代码演示
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 声明遇到函数重载
  • 代码演示
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;就是声明整个命名空间。

  • 代码演示
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.声明增强

  • 代码演示
// 声明全局变量和函数
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++中可以不加。

  • 代码演示
// 定义一个结构体
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++结构体中定义函数

  • 代码演示
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 假(赋其他值也不一定报错,但不建议,也无意义)。

  • 代码演示
// 定义一个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.三目运算符增强

  • 代码演示
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++中返回的是符合条件的变量的引用,是个变量,因此可以对其返回值赋值。

http://www.kler.cn/a/455007.html

相关文章:

  • LeetCode-最长回文子串(005)
  • 计算机网络 (10)网络层
  • json字符串或者json文件转换成相应的bean,报错“Unrecognized field xxx , not marked as ignorable”
  • 企业销售人员培训系统|Java|SSM|VUE| 前后端分离
  • Excel批量设置行高,Excel表格设置自动换行后打印显示不全,Excel表格设置最合适的行高后打印显示不全,完美解决方案!!!
  • 重温设计模式--4、组合模式
  • FOC软件 STM32CubeMX 使用
  • 【玩转OCR】 | 腾讯云智能结构化OCR在多场景的实际应用与体验
  • 头歌-边缘检测
  • AT24C02学习笔记
  • 【EDA】Gate Sizing算法
  • 基于springboot的论坛管理系统丨源码+数据库+万字文档+PPT
  • 在blender中 导出模型给threejs 用3dsprite出现缩放或者位置不对问题排查
  • 玩转OCR | 腾讯云智能结构化OCR推动跨行业高效精准的文档处理与数据提取新时代
  • linux ext4文件系统
  • 编译安装教程
  • AIGC与娱乐产业:颠覆创意与生产的新力量
  • WebRTC服务质量(12)- Pacer机制(04) 向Pacer中插入数据
  • sonarqube 安装及使用
  • 信息安全管理:开发测试安全管理checklist
  • Apache Commons Pool2—Java对象池的利器
  • 15、【OS】【Nuttx】OS裁剪,运行指定程序,周期打印当前任务
  • 三极管恒流源电路
  • 涉密行业跨网数据摆渡,光盘审计刻录输出,生产音视频刻录,电子档案长期保存应用
  • 【每日学点鸿蒙知识】推送指定页面参数、Devtools 做Web调试、图片的加载与压缩、三方so 打进hap包、Url获取参数
  • 投标是博弈:如何在有限时间内用最小风险赢得竞标