从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;  // 2return 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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue3 Hooks函数使用及封装思想

一、什么是Hooks函数&#xff1f; 想象一下&#xff0c;你在做饭&#xff0c;有一些调料你经常会用到&#xff0c;比如盐、酱油和辣椒。每次做饭时&#xff0c;你都会从柜子里拿出这些调料。如果你每次用完都把它们随便放在厨房的某个角落&#xff0c;下次做饭时就可能找不到它…

如何获取Header??

两种获取Header的方式&#xff1a; 原始方式&#xff1a; RestController RequestMapping("/param") public class ParamController {//如何获取HeaderRequestMapping("/getHeader")public String getHeader(HttpServletRequest request){String userAge…

springboot之jdbc、druid、mybatis

springboot整合jdbc spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://192.168.52.3:3306/mybatis?useUnicodetrue&characterEncodingutf-8&serverTimezoneUTCusername: rootpassword: root<?xml version"1.0" encodi…

trie树(前缀树)

前缀树 1. 前缀树的的介绍2.前缀树的实现2.1插入功能2.2删除功能2.3查找前缀和查找单词功能2.4 哈希表版本 1. 前缀树的的介绍 在计算机科学中&#xff0c;trie&#xff0c;又称前缀树或字典树&#xff0c;是一种有序树&#xff0c;用于保存关联数组&#xff0c;其中的键通常是…

MarkDown实用技巧:MarkDown中如何实现换行?

MarkDown实用技巧&#xff1a;MarkDown中如何实现换行&#xff1f; &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程 &#x1f448; 希望…

计讯物联5G RedCap网关TG463化繁为简,推动5G赋能千行百业

5G RedCap&#xff0c;全称为Reduced Capability&#xff0c;即在5G的基础上&#xff0c;对部分功能进行化繁为简后形成的新技术标准&#xff0c;故又称轻量化5G。作为高性价比下的精简技术&#xff0c;5G RedCap技术具备成本低、低功耗、兼顾5G等特点&#xff0c;能够在确保应…

【Android安全】Windows 环境下载 AOSP 源码

准备环境 安装 git 安装 Python 硬盘剩余容量最好大于 800G 打开 Git Bash&#xff0c;用 git 克隆源代码仓库 git clone https://android.googlesource.com/platform/manifest.git //没有梯子使用清华源 git clone https://aosp.tuna.tsinghua.edu.cn/platform/manifest.git这…

代码随想录算法训练营第36天 | 738.单调递增的数字 ,968.监控二叉树

贪心算法章节理论基础&#xff1a; https://programmercarl.com/%E8%B4%AA%E5%BF%83%E7%AE%97%E6%B3%95%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 738.单调递增的数字 题目链接&#xff1a;https://leetcode.cn/problems/monotone-increasing-digits/ 思路&#xff1a; …

论文精读--VAE

自编码器(Auto-Encoder)是学一个特征能够代表输入的图像 而VAE则为数据的隐变量加上先验——将隐变量限制为一个标准正态分布&#xff0c;也就是学一个具有代表性的分布 Abstract How can we perform efficient inference and learning in directed probabilistic models, in…

鸿蒙linux内核的L1设备服务开发详解

鸿蒙linux内核的L1设备服务开发详解 ​ 鸿蒙基于linux内核的L1设备的系统基于面向服务架构&#xff0c;提供了服务开发、服务的子功能开发、对外接口的开发、以及多服务进程、进程间服务调用的开发能力。现对此基座下的服务进行剖析并以实例方式进行讲解。 一、简介 在L1设备…

git忽略某些文件(夹)更改方法

概述 在项目中,常有需要忽略的文件、文件夹提交到代码仓库中,在此做个笔录。 一、在项目根目录内新建文本文件,并重命名为.gitignore,该文件语法如下 # 以#开始的行,被视为注释. # 忽略掉所有文件名是 a.txt的文件. a.txt # 忽略所有生成的 java文件, *.java # a.j…

Time Travel

题目链接 解题思路 由于所有边集中的边加起来的总和至多为&#xff0c;无向图即&#xff0c;可以存下所以直接对所有边集中的边进行建边&#xff0c;同时对于每条边&#xff0c;记录其所在边集号对于每个边集&#xff0c;由大到小维护其能通过的时间点然后从1号跑最短路到当前…

Flutter开发框架

Flutter 技术栈是指用于构建应用程序的一系列技术和工具&#xff0c;这些技术和工具都是围绕 Flutter 框架组织的。Flutter 是由谷歌开发的开源 UI 开发工具包&#xff0c;用于从单一代码库开发跨平台应用程序&#xff0c;包括 Android、iOS、Web、以及桌面应用程序&#xff08…

操作系统功能

▶1.进程管理 简单地说&#xff0c;进程是程序的执行过程。程序是静态的&#xff0c;它仅仅包含描述算法的代码&#xff1b;进程是动态的&#xff0c;它包含了程序代码、数据和程序运行的状态等信息。进程管理的主要任务是对CPU资源进行分配&#xff0c;并对程序运行进行有效的…

高级语言期末2011级A卷(软件学院)

1.编写函数&#xff0c;判定正整数m和n&#xff08;均至少为2&#xff09;是否满足&#xff1a;数m为数n可分解的最小质因数&#xff08;数n可分解的最小质因数为整除n的最小质数&#xff09; 提示&#xff1a;判定m为质数且m是n的最小因数 #include <stdio.h> #include…

DiffiT | 英伟达提出用于图像生成的扩散ViT架构DiffiT,达成新SOTA!

本文首发于AIWalker&#xff0c;欢迎关注。 https://arxiv.org/abs/2312.02139 https://github.com/NVlabs/DiffiT 扩散模型以其强大的表达能力和高样本质量在许多领域得到了新的应用。对于样本生成&#xff0c;这些模型依赖于通过迭代去噪生成图像的去噪神经网络。然而&#…

坚持刷题|二叉树展开为链表

文章目录 题目考察点代码实现实现总结扩展问题用递归的方式实现在展开二叉树为链表的过程中&#xff0c;递归和迭代两种方法各有什么优缺点&#xff1f;可能的扩展问题 Hello&#xff0c;大家好&#xff0c;我是阿月。坚持刷题&#xff0c;老年痴呆追不上我&#xff0c;今天刷&…

LTD营销枢纽2023年度功能升级回顾

在过去的2023年&#xff0c;我们的团队致力于不断进步和创新。经过一年的不懈努力&#xff0c;我们共发布了50次的系统升级&#xff0c;引入了16种全新的解决方案与业务应用&#xff0c;并实施了1363项各类细致优化。 这些更新和改进不仅在我们的营销枢纽系统现有功能的基础上实…

Groovy(第二节) Groovy之HelloWorld

目录 为什么要学习 Groovy? 入门非常容易 用 Groovy 编写的 Hello World 运行 Groovy 示例

PHP函数 “password_hash“ 哈希密码

哈希函数是一种将输入转换为固定长度字符串的方法&#xff0c;这个过程是不可逆的&#xff0c;也就是无法从哈希值还原出原始输入。通过将密码进行哈希处理&#xff0c;即使数据库泄露&#xff0c;攻击者也无法简单地获取到用户密码。 在PHP中&#xff0c;我们可以使用 "…