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

从0到1学C++ 第2篇 认识C++面向过程编程的特点

一. 本篇要学习的内容和知识结构概览


二. 知识点逐条分析

1. 使用函数重载

C++允许为同一个函数定义几个版本, 从而使一个函数名具有多种功能, 这称之为函数重载.

像这样: 虽然函数名一样, 但是参数列表不一样, 一个求两个整型参数的最大值, 一个求三个整型参数的最大值.

int getMax(int a, int b) {
    if (a > b) {
        return a;
    } else {
        return b;
    }
}

int getMax(int a, int b, int c) {
    if (a > b) {
        if (a > c) {
            return a;
        } else {
            return c;
        }
    } else {
        if (b > c) {
            return b;
        } else {
            return c;
        }
    }
}
复制代码

2. 新的基本数据类型及其注意事项

a. void是无类型标识符, 只能声明函数的返回值类型, 不能声明变量

b. C++当中有bool类型, 而C中没有

c. C++的常量分为符号常量, 浮点常量, 整数常量

   像这样:


我们可以通过屏幕输出来查看011, 11, 0x11各代表十进制的多少

int a = 011; // 八进制数
cout << a << endl; // 以十进制格式输出

int b = 11; // 十进制数
cout << b << endl; // 以十进制格式输出

int c = 0x11; // 十六进制
cout << c << endl; // 以十进制格式输出
复制代码

3. 动态分配内存

申请内存空间: new 类型名[size], 申请可以存size个该数据类型对象的存储空间

释放内存空间: delete 指针名;

像这样:

int * p; // 声明int类型指针
p = new int[5]; // 申请5个int类型数据的存储空间
cout << p << endl; // 该内存空间的首地址
delete p; // 释放内存空间
复制代码

4. 引用

为现有对象起个别名, 别名代表的内存空间与引用对象的内存空间是一样的

引用的声明方式: 数据类型(类型名) & 别名 = 对象名;

&的位置无关紧要

像这样:

int c = 10;
int & d = c;
int& e = c;
int &f = c;
cout << c << endl;
cout << d << endl;
cout << e << endl;
cout << f << endl;复制代码

我们再进一步的使用它

int a = 5; // 定义int类型变量, 并赋值
cout << a << endl; // 输出变量a的值: 5
cout << &a << endl; // 输出变量a的地址: 0x7ffeefbff52c

int & b = a;
cout << b << endl; // 引用b的值: 5
cout << &b << endl; // 引用b的地址: 0x7ffeefbff52c复制代码

可以看到, 上下两组输出结果是一样的, 也就是说引用b, 和变量a都是代表的同一块内存地址

所以更改b的值, a的值也会变

b = 8;

cout << a << endl;
复制代码

注意: 引用, 就是给一块已经存在的内存添加一个新的标识符, 所以使用引用没有分配新的内存空间, 所以可以通过引用来修改原来的对象, 但是不能有空引用, 它必须和一声正确的存储区域关联

像这样: 是错误的

int & b; // 编译器提示信息: Declaration of reference variable 'b' requires an initializer, 变量b需要一个初始化器

引用的作用

a. 引用用于函数的参数表, 不产生临时对象, 提高安全性和执行效率

void swap(int & a, int & b) {
int temp = a;
a = b;
b = temp;
}

int a = 5;
int b = 10;
cout << "交换前 " << "a的值:" << a << " b的值:" << b << endl;
swap(a, b);
cout << "交换后 " << "a的值:" << a << " b的值:" << b << endl;
复制代码

b. 引用用于函数返回值 用到的时候很少, 因为不安全, 你可能问访问到一个已经被释放的对象

引用可以这么使用

int a = 5;
int & b = a; // 声明引用
int * p = &a; // 声明指向变量的指针
int * q = &b; // 声明指向引用的指针
int * & r = p; // 声明指针对指针的引用 (p, r是指针, 等号左边 * 代表声明的r是指针, &代表声明的r是引用)复制代码

但是不能这么使用

int & & s = a; // 不能声明引用的引用
复制代码

指针和引用的区别和联系

联系: 它们都会对内存地址上存在的变量进行修改, 但引用不占用新的地址, 节省开销

区别: 指针是低级的直接操作内存地址的机制, 可由整型数强制类型转换得到, 功能强大, 但是容易出错, 引用是较高级的封装了指针的特性, 不直接操作内存地址, 不可强制类型转换得到, 安全性高

5. 对指针使用const限定符

a. 指向常量的指针

int a = 5;
int b = 8;
const int * p = &a; // 指向常量的指针, 也就是"*p="不成立, 也就是不能通过指针p修改指向的内存地址中的值, 但是p的值可以更改
*p = 10; // 错误
p = &b; // 正确
复制代码
b. 常量指针

int a = 5;
int b = 8;
int * const p = &a; // 常量指针, 也就是"p="不成立, 也就是p的值不能更改, 但是是它所指向的内存地址中的值可以修改
*p = 10; // 正确
p = &b; // 错误

复制代码

c. 指向常量的常量指针

int a = 5;
int b = 8;
const int * const p = &a; // 指向常量的的常量指针, 既不可以通过p修改它所指向的内存地址中的值, 也不可更改p的值
*p = 10; // 错误
p = &b; // 错误复制代码

6. 泛型算法应用于普通数组

// 定义数组
int a[] = {3, 2, 1, 5, 4};
int b[5] = {};

// 数组反转
//    reverse(a, a + 5);

// 升幂排序
//    sort(a, a + 5);

// 降幂排序
//    sort (a, a+5, greater<int>());

// 复制数组内容
//    copy(a, a + 5, b);

// 逆向复制数组a中的内容到数组b
//    reverse_copy(a, a + 5, b);

// 检索
//    int * p = find(a, a + 5, 5);
//    cout << p << endl;
//    cout << a + 5 << endl;
//    if (p == a + 5) {
//        cout << "没有值为5的数组元素" << endl;
//    } else {
//        cout << "有值为5的数组元素" << endl;
//    }

// 正向输出
copy(a, a + 5, ostream_iterator<int>(cout, "数字 "));

cout << endl;

// 逆向输出
reverse_copy(a, a + 5, ostream_iterator<int>(cout, "数字 "));

for (int i = 0; i < 5; i++) {
    cout << a[i] << " ";
}

cout << endl;

for (int i = 0; i < 5; i++) {
    cout << b[i] << " ";
}

cout << endl;复制代码

7. 程序的编辑, 编译, 连接, 运行的基本概念

使用编辑器编辑一个C++源程序, 也就是源文件, 扩展名为.cpp, 像这样: Hello.cpp;

使用C++编译器对这个源程序进行编译, 产生目标文件, 扩展名为.obj, 像这样: Hello.obj;

使用连接程序, 将目标文件与系统库连接, 产生可执行文件, 扩展名为.exe, 你这样: Hello.exe

任何时候我们都不要忘记语言只是我们解决问题的工具, 思想才是我们解决问题的本质, 技术不深, 我们可以去查, 去练习, 而思想只有慢慢的去陪养, 去思考, 去总结!

本系列文章会持续更新! 大家踊跃的留下自己的脚印吧!

????????



相关文章:

  • Java01
  • 苹果下调财收预期,致使股价大跌近10%,万亿身家缩水近一半
  • 图像的等距变换,相似变换,仿射变换,射影变换
  • 解决NoclassDefFoundError 打印一个类的java路径
  • 从Lucene到Elasticsearch:从 Lucene 到 ElasticSearch
  • 【文文殿下】ExBSGS
  • [HNOI2008]Cards
  • Facebook 2018 年度开源回顾:新增开源项目 153 个
  • 游戏开发中的抛物线(贝塞尔曲线)
  • Vue UI框架库开发介绍
  • MultipartFile 不能直接 转成File对象
  • react native 包学不包会系列--react native开发基础知识
  • 老鼠的商议
  • (轉貼) 寄發紅帖基本原則(教育部禮儀司頒布) (雜項)
  • Silverlight 1.1架构图
  • canvas 绘制双线技巧
  • Cumulo 的 ClojureScript 模块已经成型
  • git 常用命令
  • HTTP--网络协议分层,http历史(二)
  • Java 多线程编程之:notify 和 wait 用法
  • k个最大的数及变种小结
  • Laravel5.4 Queues队列学习
  • oschina
  • PHP 小技巧
  • springboot_database项目介绍
  • TypeScript实现数据结构(一)栈,队列,链表
  • 订阅Forge Viewer所有的事件
  • 设计模式 开闭原则
  • 通过npm或yarn自动生成vue组件
  • JavaScript 新语法详解:Class 的私有属性与私有方法 ...
  • TPG领衔财团投资轻奢珠宝品牌APM Monaco
  • 选择阿里云数据库HBase版十大理由
  • $.ajax()
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (二)基于wpr_simulation 的Ros机器人运动控制,gazebo仿真
  • (二十四)Flask之flask-session组件
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (附源码)计算机毕业设计SSM在线影视购票系统
  • (六)vue-router+UI组件库
  • (转载)Google Chrome调试JS
  • .NET 4 并行(多核)“.NET研究”编程系列之二 从Task开始
  • .NET CF命令行调试器MDbg入门(四) Attaching to Processes
  • .net CHARTING图表控件下载地址
  • .net core IResultFilter 的 OnResultExecuted和OnResultExecuting的区别
  • .NET Core 成都线下面基会拉开序幕
  • .net framework4与其client profile版本的区别
  • .NET 设计一套高性能的弱事件机制
  • .Net6 Api Swagger配置
  • .NET开发者必备的11款免费工具
  • .NET开源项目介绍及资源推荐:数据持久层
  • .NET连接数据库方式
  • .Net转Java自学之路—SpringMVC框架篇六(异常处理)
  • /使用匿名内部类来复写Handler当中的handlerMessage()方法
  • @RequestMapping 的作用是什么?
  • []C/C++读取串口接收到的数据程序