从C到C++

二、从C到C++

本章介绍一些C++拓展的非面向对象功能。

  1. 引用(掌握)

1.1 概念

引用从一定程度上讲是一个指针的平替,几乎被所有面向对象编程语言所使用。引用相当于对某一个目标变量起”别名“。

操作引用与操作原变量完全一样。

#include <iostream>

using namespace std;

int main()
{
    int a = 1;
    // b是a的引用
    int &b = a;

    cout << a << " " << &a << endl; //1 0x61fe88
    cout << b << " " << &b << endl; //1 0x61fe88
    return 0;
}

1.2 引用的性质

  • 可以改变引用的值,但是不能再次成为其他变量引用。

#include <iostream>

using namespace std;

int main()
{
    int a = 1;
    // b是a的引用
    int &b = a;
    int c = 3;
    b = c; // 3 只是赋值,不是引用,b还是a的引用

    cout << a << " " << &a << endl; //3 0x61fe88
    cout << b << " " << &b << endl; //3 0x61fe88
    cout << c << " " << &c << endl; //3 0x61fe84
    return 0;
}

  • 声明引用的时候,必须要初始化。

#include <iostream>

using namespace std;

int main()
{
    int a = 1;
//    int &b; // 错误 引用必须要初始化。

    cout << a << " " << &a << endl; //3 0x61fe88

    return 0;
}

  • 声明引用的时候,不能初始化为null

#include <iostream>

using namespace std;

int main()
{
    int a = 1;
    // int &b = nullptr; // 错误引用不能初始化为null
//    int &b = null;
    cout << a << " " << &a << endl; //3 0x61fe88

    return 0;
}

  • 声明引用的时候,初始化的值可以是纯数值,但是此时要用const关键字修饰引用,表示该引用为常量引用,这样引用的值不可变。

#include <iostream>

using namespace std;

int main()
{
    const int &a = 1;   // 常量引用
    // a = 2; // 错误常量引用的数值不能被改变

    cout << a << " " << &a << endl; //3 0x61fe88

    return 0;
}

  • 可以将变量引用的地址赋值 给一个指针,此时指针指向的还是原来的变量。

#include <iostream>

using namespace std;

int main()
{
    int a = 1;
    int &b = a;
    int *c = &b;

    cout << a << " " << &a << endl; // 1 0x61fe84
    cout << b << " " << &b << endl; // 1 0x61fe84
    cout << *c << " " << c << endl; // 1 0x61fe84

    return 0;
}

  • 可以使用const修饰引用,此时如果原变量的值改变了,引用的值也会改变。

#include <iostream>

using namespace std;

int main()
{
    int a = 1;
    const int &b = a;
    a++;
//    b++;  // 错误的,b是只读的

    cout << a << " " << &a << endl; // 2 0x61fe84
    cout << b << " " << &b << endl; // 2 0x61fe84

    return 0;
}

1.3 引用的参数

写一个函数,函数有两个参数a和b,函数 的功能是交换两个传入的参数【原来】变量的值。

#include<iostream>
#include <string.h>
using namespace std;

// 只是test1内部进行相互交换了
// 不符合需求
void test1(int a,int b)
{
    int t = a;
    a = b;
    b = t;
}

// C语言的指针
void test2(int *a,int *b)
{
    *= *a^*b;
    *= *a^*b;
    *= *a^*b;
}

// C++ 编程方式
void test3(int &a,int &b)
{
    a = a^b;
    b = a^b;
    a = a^b;
}

int main()
{
    int a = 1;
    int b = 2;
    test3(a,b);
    cout << a << endl;
    cout << b << endl;
    return 0;
}

引用作为参数进行定义的时候,在参数传递时,是不会产生副本的,这样会提高运行效率,我们在正常编程中,建议使用引用作为参数进行传递。

引用参数,在不参与计算的情况,我们建议使用const进行修饰。以达到引用安全的目的。

  1. 赋值(熟悉)

通常编程当中使用=进行赋值操作,C++新增了新的赋值语法。

#include<iostream>
#include <string.h>
using namespace std;


int main()
{
    int a(1);   // int a = 1;
    cout << a << endl;
    int b(a);   // int b = a;
    cout << b << endl;

    int c(a+b); // int c = a + b;
    cout << c << endl;  // 2

    return 0;
}

C++11里对上述写法又进行了升级

#include<iostream>
#include <string.h>
using namespace std;


int main()
{
    double b = 3.14;
    int b1 = b;
    int b2(b);
    int b3{b};  // C++11新增的 对数据窄化做出警告

    cout << b1 << endl; // 3 数据窄化
    cout << b2 << endl; // 3 数据窄化
    cout << b3 << endl; // 3 数据窄化
    return 0;
}

  1. 键盘输入(掌握)

可以使用cin把用户在命令行中输入的内容赋值到变量中。

cin与cout一样,都属于头文件iostream中标准输入输出流。

#include<iostream>
#include <string.h>
using namespace std;

int main()
{
    int a;
    // C++ 的字符串是string
    string str;

    cout << "请输入一个数字和字符串:" << endl;
    cin >> a >> str ; // 接收键盘输入:一个整数和一个字符串,可以连续输入。
    cout << a << endl;
    cout << str << endl;

    return 0;
}

  1. string 字符串类(掌握)

string 不是C++的基本数据类型,他是一个C++标准库中的字符串类,使用时需要引入头文件,#include<string>,而不是string.h

string在绝大多数情况下,可以替代C语言中字符串,不必担心内存是否足够,和字符串长度等,其中内部还包含了很多字符串处理函数,可以完成各种情况下的字符串处理功能。

string和C语言相同,字符串编码使用ASCII编码,不支持中文。

#include<iostream>
using namespace std;


int main()
{
    string str = "helloworld";
    cout << str.size() << endl; // 10字符串长度
    cout << str.length() << endl; // 10字符串长度

    cout << str[1] << endl; // e
    cout << str.at(5) << endl; // w

    return 0;
}

两种方式都可以,但是在C++中更推荐你使用at函数。原因时at函数更加安全。at函数的运行效率慢。[ ]效率更高。

#include<iostream>
using namespace std;


int main()
{
    string str = "helloworld";
    cout << str.size() << endl; // 10字符串长度
    cout << str.length() << endl; // 10字符串长度

    // cout << str[100] << endl; // 什么都不输出,也不报错,不安全
    cout << str.at(100) << endl; // 安全的,越界会报异常。

    return 0;
}

string 类支持多种遍历方式

  • 普通循环(for循环)
  • for each循环 C++11

#include<iostream>
using namespace std;


int main()
{
    string str = "helloworld";
    // 以for循环的方式遍历输出字符串
    for(int i = 0; i <str.size(); i++)
    {
        cout << str.at(i);
    }
    cout << endl;

    // for each的方式进行循环遍历字符串
    for(char i : str)
    {
        cout <<i;
    }

    return 0;
}

  1. 函数

5.1 内联函数(掌握)

内联函数用于取代C语言中宏定义的函数。内联函数的正确使用可以提升程序的执行效率。内联函数在编译的时候,直接把函数体展开到主函数中编译,在运行期间可以减少调用的开销。(以空间换时间)

通常将具有以下性质的函数写为内联函数:

  • 代码长度5行以内。
  • 不能包含复杂的控制语句。
  • 被频繁调用

#include<iostream>
using namespace std;

// 声明成-内联函数
inline void show(string str)
{
    cout << str << endl;
}

int main()
{
    show("nihao");
    return 0;
}

内联函数关键字:inline

后续学习的成员函数都默认添加了inline修饰。

但是我们手动添加的inline关键字,将函数声明称内联函数。这个不是我们能决定的。我们只是给编译器提一个建议,编译器有自己的判断准则。具体是否能变成内联函数,还是编译器自己决定的。

5.2 函数重载 overload(重点)

C++中允许多个函数使用同一个名称,这种写法就是函数重载。函数重载要求函数名称相同,但是参数不同(类型或者数量)或者前后顺序不同。与返回值和其他因素无关。

#include <iostream>
using namespace std;

void print_show(int i,double d)
{
    cout << "调用了int重载" << i << endl;
}

//void print_show(double d)
//{
//    cout << "调用了double重载" << d << endl;
//}

//void print_show(float f)
//{
//    cout << "调用了float重载" << f << endl;
//}

void print_show(string str)
{
    cout << "调用了string重载" << str << endl;
}

int main()
{
    print_show(6,5.4);
    return 0;
}

5.4 哑元函数(熟悉)

函数的参数只有类型,没有名称,有这样的参数的函数就是哑元函数。

#include <iostream>
using namespace std;

// 哑元函数
void print_show(int)
{
    cout << "调用了int重载" << endl;
}


void print_show(string str)
{
    cout << "调用了string重载" << str << endl;
}

int main()
{
    print_show(6);  // 尽管函数内不用参数,但是还是需要传递参数
    return 0;
}

作用1:哑元函数用来区分函数重载。

作用2:运算符重载中会用到。

#include <iostream>
using namespace std;

// 哑元函数
void print_show(int i,int)
{
    cout << "调用了int1重载" << endl;
}

void print_show(int i)
{
    cout << "调用了int2重载" << endl;
}


void print_show(string str)
{
    cout << "调用了string重载" << str << endl;
}

int main()
{
    print_show(6,1);  // 尽管函数内不用参数,但是还是需要传递参数
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/417410.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

工厂模式 详解 设计模式

工厂模式 其主要目的是封装对象的创建过程&#xff0c;使客户端代码和具体的对象实现解耦。这样子就不用每次都new对象&#xff0c;更换对象的话&#xff0c;所有new对象的地方也要修改&#xff0c;违背了开闭原则&#xff08;对扩展开放&#xff0c;对修改关闭&#xff09;。…

Unity UI适配规则和对热门游戏适配策略的拆解

前言 本文会介绍一些关于UI适配的基础概念&#xff0c;并且统计了市面上常见的设备的分辨率的情况。同时通过拆解目前市面上较为成功的两款休闲游戏Royal Match和Monopoly GO(两款均为近期游戏付费榜前几的游戏)&#xff0c;大致推断出他们的适配策略&#xff0c;以供学习和参…

go并发模式之----阻塞/屏障模式

常见模式之一&#xff1a;阻塞/屏障模式 定义 顾名思义&#xff0c;就是阻塞等待所有goroutine&#xff0c;直到所有goroutine完成&#xff0c;聚合所有结果 使用场景 多个网络请求&#xff0c;聚合结果 大任务拆分成多个子任务&#xff0c;聚合结果 示例 package main ​…

Delegate动画案例(P30 5.6delegate动画)

一、ListElement&#xff0c;ListModel&#xff0c;ListView 1. ListElement ListElement 是 QML 中用于定义列表项的元素。它可以包含多个属性&#xff0c;每个属性对应列表项中的一个数据字段。通过在 ListModel 中使用 ListElement&#xff0c;可以定义一个列表的数据模型…

USB-C接口:办公新宠,一线连接笔记本与显示器

USB-C接口如今已成为笔记本与显示器连接的优选方案。无需担心正反插错&#xff0c;支持雷电4和DP视频信号输出&#xff0c;高速数据传输&#xff0c;还有最高100W的快充功能&#xff0c;真是方便又实用&#xff01; 一线连接&#xff0c;多功能融合 通过这个接口&#xff0c;你…

面试笔记系列三之spring基础知识点整理及常见面试题

目录 如何实现一个IOC容器? 说说你对Spring 的理解&#xff1f; 你觉得Spring的核心是什么&#xff1f; 说一下使用spring的优势&#xff1f; Spring是如何简化开发的&#xff1f; IOC 运行时序 prepareRefresh() 初始化上下文环境 obtainFreshBeanFactory() 创建并…

瑞_23种设计模式_外观模式

文章目录 1 外观模式&#xff08;Facade Pattern&#xff09;1.1 介绍1.2 概述1.3 外观模式的结构 2 案例一2.1 需求2.2 代码实现 3 案例二3.1 需求3.2 代码实现 4 jdk源码解析 &#x1f64a; 前言&#xff1a;本文章为瑞_系列专栏之《23种设计模式》的外观模式篇。本文中的部分…

如何在Windows部署TortoiseSVN客户端并实现公网连接内网VisualSVN服务端

文章目录 前言1. TortoiseSVN 客户端下载安装2. 创建检出文件夹3. 创建与提交文件4. 公网访问测试 前言 TortoiseSVN是一个开源的版本控制系统&#xff0c;它与Apache Subversion&#xff08;SVN&#xff09;集成在一起&#xff0c;提供了一个用户友好的界面&#xff0c;方便用…

Flutter开发之Slider

Flutter开发之Slider 本文是关于介绍Slider相关属性的含义。 class SliderThemeData {/// slider轨道的高度 final double? trackHeight; /// 滑块滑过的轨道颜色 final Color? activeTrackColor; /// 滑块未滑过的轨道颜色 final Color? inactiveTrackColor; /// 滑块滑过…

JavaEE——简单认识JavaScript

文章目录 一、简单认识 JavaScript 的组成二、基本的输入输出和简单语法三、变量的使用四、JS 中的动态类型图示解释常见语言的类型形式 五、JS中的数组六、JS 中的函数七、JS 中的对象 一、简单认识 JavaScript 的组成 对于 JavaScript &#xff0c;其中的组成大致分为下面的…

多线程如何设计?一对多/多对一/多对多

二、14个多线程设计模式 参考原文&#xff1a;https://www.cnblogs.com/rainbowbridge/p/17443503.html single Thread 模式 一座桥只能通过一个人 Single Thread模式是一种单线程设计模式&#xff0c;即在一个应用程序中只有一个主线程、一个事件循环&#xff0c;对外只提…

【C语言基础】:深入理解指针(一)

文章目录 一、内存和地址1. 内存2. 如何理解编址 二、指针变量和地址2.1 取地址操作符(&)2.2 指针变量和解引用操作符(*)2.2.1 指针变量2.2.2 如何拆解指针变量2.2.3 解引用操作符 2.3 指针变量的大小 三、指针变量类型的意义3.1 指针的解引用3.2 指针 - 整数3.3 void*指针…

什么是物联网?

今天这篇文章写的相关内容就是带领大家了解什么是物联网&#xff0c;之前写的文章大多都是一些物联网的未来&#xff0c;行业的解决方案等&#xff1b;话不多说开始进入正题吧! 物联网(IoT)是一个包罗万象的术语&#xff0c;指的是越来越多的电子产品&#xff0c;它们不是传统的…

vue2+elementui上传照片(el-upload 超简单)

文章目录 element上传附件&#xff08;el-upload 超详细&#xff09;代码展示html代码data中methods中接口写法 总结 element上传附件&#xff08;el-upload 超详细&#xff09; 这个功能其实比较常见的功能&#xff0c;后台管理系统基本上都有&#xff0c;这就离不开element的…

计算机组成原理4-存储器的层次结构与程序访问的局部性原理

1. 磁盘 1.磁盘的结构 磁盘由盘片构成&#xff0c;每个盘片包含两面 每面由一组称为磁道的同心圆组成 每个磁道划分为一组扇区&#xff0c;扇区之间由间隙隔开 同一半径上的所有磁道组成一个柱面2.磁盘的容量 容量&#xff1a;磁盘上可以存储的最大位数。 决定因素&#xff1a…

【玩转408数据结构】线性表——双链表、循环链表和静态链表(线性表的链式表示 下)

知识回顾 在前面的学习中&#xff0c;我们已经了解到了链表&#xff08;线性表的链式存储&#xff09;的一些基本特点&#xff0c;并且深入的研究探讨了单链表的一些特性&#xff0c;我们知道&#xff0c;单链表在实现插入删除上&#xff0c;是要比顺序表方便的&#xff0c;但是…

IDEA利用鼠标调整字体大小

就可以按住ctrl和鼠标调节代码字体的大小啦&#xff01; 如果有用&#xff0c;记得给我来个赞~ 谢啦&#xff01;

【python基础学习07课_函数基础课】

一、函数的基础知识 一、函数的作用是用来干什么的&#xff1f; 函数在编程中是一个组织好的、可重复使用的代码块&#xff0c;用于执行一个特定的任务。具体来说&#xff0c;函数的常见作用包括&#xff1a;1、执行计算或数据处理。 2、控制程序的流程&#xff0c;如条件判断…

Java+SpringBoot+Vue+MySQL:员工健康管理技术新组合

✍✍计算机毕业编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java、…

压缩式 交换式 碎片整理 :(使碎片减少或没有)

交换式碎片整理 首先流程 是 p3这个程序在运行&#xff0c;p1p2p4 的话在等待 &#xff0c;然后p3这时要多用3个内存块&#xff0c;这是 p4 通过拷贝&#xff0c;将内存拷贝到磁盘上&#xff0c;对应的数据也是从主存中cp到磁盘此时主存多出3个内存块给p3继续使用 2.压缩式碎片…