C++学习之路,从0到精通的征途:入门基础

目录

一.C++的第一个程序

二.命名空间

1.namespace的价值

2.命名空间的定义

3.命名空间使用

三.C++的输入与输出

1.<iostream>

2.流

3.std(standard)

四.缺省参数 

1.缺省参数的定义

 2.全缺省/半缺省

3.声明与定义

​五.函数重载

1.参数个数不同

2.参数类型不同

3.参数类型顺序不同

函数返回值不同是否能作为重载条件?

带有缺省参数的函数能构成重载吗?

六.引用

1.引用的概念和定义

2.引用的特性  

2.1引用在定义是必须初始化

2.2一个变量可以有多个引用

2.3引用一旦引用一个实体,再不能引用其他实体 

3.引用的使用

3.1引用传参

3.2引用作返回值

4.const引用

5.指针和引用的关系

七.inline

 1.inline的定义与概念

2.inline的特性

3.inline与宏函数的比较

八.nullptr

九.总结 


一.C++的第一个程序

        第一个程序当然是“Hello World”,不过这里我们使用C++的语法进行实现。

        在实现前,我们创建的文件必须得是.cpp文件,编译器在识别后缀为.cpp后才会调用C++编译器,这里后缀改为.c文件是会报错的。

#include<iostream>
using namespace std;int main()
{cout << "Hello World" << endl;return 0;
}

运行结果:

        这里对于代码有疑问是正常的,接下来我们来逐一讲解。

二.命名空间

1.namespace的价值

        在C语言中如果一个声明的变量名刚好与其他变量名重复或者与函数名等重复,则会出现报错,例如下面这段代码:

#include<stdio.h>
#include<stdlib.h>int rand = 0;int main()
{printf("%d\n", rand);return 0;
}

报错片段:

        可以看到报错语句为重定义:以前的定义是函数。

        在这里我们期望rand是int类型,但rand是函数类型,这说明由于stdlib.h中rand()的存在,编译器将rand识别为了函数,在C语言中如果要解决这样的问题只能再取一个其他变量名,但在C++中我们可以用命名空间去解决命名冲突的问题。

2.命名空间的定义

        定义命名空间,需要用到关键字namespace,后面跟命名空间的名字,这里用mySpace举例,再跟一对大括号{},{}中可以定义命名空间的成员,成员可以是变量/函数/类型等。

代码演示:

namespace mySpace
{int rand = 0;int Add(int left, int right){return left + right;}struct Node{struct Node* next;int val;};
}

        namespace本质是定义一个域,在C语言中由于不用域中可以定义同名变量,namespace也类似与这种特性,namespace定义的域与全局域各自独立,其通过域隔离解决了同名冲突的问题,且命名空间不会影响变量的生命周期。

        命名空间只能定义在全局,同时namespace也可以嵌套定义。

代码演示:

namespace mySpace
{namespace s1{int rand = 0;int a = 1;}namespace s2{int rand = 10;int a = 11;}
}
	printf("%d\n", mySpace::s1::a);printf("%d\n", mySpace::s2::a);

        在调用的过程中,我们使用域作用限制符::,它能在编译时通过指定域的形式进行查找。

        如第一条printf语句,就是访问MySpace中命名空间s1中的整型变量a,打印值为1。

运行结果:

·        在项目目工程文件中,同名的namespace会认为是一个namespace不会冲突:

·        我们再定义一个头文件,并创建一个同名namespace。

        

        在包含头文件后可以看到,程序并未报错,并成功输出b的值,这说明编译器认为两个namespace并不冲突,为同一个命名空间。

3.命名空间使用

         编译器的查找规则为: 1.先局部再全局        2.指定域中查找

        所以如果直接查找命名空间中的变量名而并未指定,则会报错,参考下面程序:

        如果要正确使用命名空间中定义的变量/函数,有三种方式:

        1.运用域作用限制符,指定命名空间访问,项目中推荐使用。

        2.使用using将命名空间中某个频繁使用的变量/函数展开,项目中不推荐使用。

这样就可以让上面的程序不报错了,但由于将命名空间中的a展开,可能会有同名冲突的风险。
3.用using展开命名空间中的所有成员项目中不推荐,冲突风险大,日常练习时方便推荐使用。

三.C++的输入与输出

1.<iostream>

        C++中的输入与输出不再使用<stdio.h>,而是用<iostream>,iostream是Input Output Stream 的缩写,库中定义了标准的标准的输入输出对象,其中包含<iostream>也会间接包含<stdio.h>,所以也能使用printf和scanf,不同编译器可能会报错。

2.流

        std::cin 是 istream 类的对象,它主要面向窄字符(narrow characters (of type char))的标准输入流。

        std::cout 是 ostream 类的对象,它主要面向窄字符的标准输出流。

        std::endl 是⼀个函数,流插入输出时,相当于插入一个换行字符加刷新缓冲区。现在可以简单理解为换行符。  

        <<是流插入运算符,>>是流提取运算符。(C语言中用这两个运算符做位运算左移/右移)

示例:

        C++中的输入输出不再需要像C语言那样手动指定格式,流可以自动识别变量类型,也能更好的支持自定义类型的输入输出。

例如:

3.std(standard)

        C++的标准库放在一个为std的命名空间中,cout/cin/endl都属于标准库,所以需要通过命名空间std去使用他们。   

        与命名空间的使用方式相同:

        1.域作用操作符,指定命名空间访问

	std::cin >> a;std::cout << a << std::endl;

        2.using展开频繁使用的成员

#include<iostream>
using std::cout;
using std::endl;int main()
{int a = 0;std::cin >> a;cout << a << endl;return 0;
}

        3.using展开命名空间,项目中不推荐使用,推荐日常练习

using namespace std;

四.缺省参数 

1.缺省参数的定义

        缺省参数是声明或定义函数时为函数的参数指定⼀个缺省值。调用该函数时,如果并未传输指定的实参,则直接采用缺省值,否则使用指定的实参,缺省参数分为全缺省和半缺省参数。(有些地方把缺省参数也叫默认参数)

如图:

 2.全缺省/半缺省

        全缺省就是所有形参给缺省值,示例:

        半缺省就是部分下形参给缺省值,示例:

        由于这里是半缺省,a没有缺省值,所以在调用函数时必须传至少一个参数。                

        同时C++规定半缺省参数必须从右往左依次连续缺省,不能间隔跳跃给缺省值。

报错片段:

        带有缺省参数的函数调用,传参时不可跳跃,必须从左到右依次给实参。

3.声明与定义

        带有缺省参数的函数在声明和定义分离时,不能同时给缺省参数,规定必须在声明中出现。

五.函数重载

        C++中支持在同一作用域下同名函数的出现,但必须这些函数的形参个数不同,形参类型不同,或形参类型顺序不同,这样可以让函数调用呈现多态行为,更加灵活。

1.参数个数不同

2.参数类型不同

3.参数类型顺序不同

函数返回值不同是否能作为重载条件?

        由于函数名和参数相同,在调用函数时无法根据返回值的不同来区分到底要调用哪个函数,所以会报错,显示函数f重定义

        所以函数返回值不同并不能作为重载条件。

带有缺省参数的函数能构成重载吗?

        可以看到报错语句为对重载函数的调用不明确,说明带有缺省参数的函数构成重载,但在函数调用时,编译器不知道调用的是哪个函数,存在歧义,所以会导致报错。

六.引用

1.引用的概念和定义

        引用不是定义一个新变量,而是给已有的变量取一个别名,编译器不会为引用变量开辟空间,引用变量与被引用的变量使用同一块内存空间。

类型& 引用别名 = 引用对象

	int a = 0;int& b = a;int& c = a;

        b,c是变量a的别名。这里引用符号&与取地址符号相同,根据用法区分即可。

    int& d = b;

        也可以给别名b取别名为d,所以d也是a的别名         

      由于b,c,d是a的别名,四者同用一块内存空间,在++d后,a,b,c,d的值全部自增一,并且从运行结果可以看出四个变量的地址相同,共用一块空间。 

2.引用的特性  

2.1引用在定义是必须初始化

2.2一个变量可以有多个引用

2.3引用一旦引用一个实体,再不能引用其他实体 

3.引用的使用

        引用在实际操作中主要用来作引用传参引用作返回值,从而减少拷贝,提高效率,在改变引用对象的同时改变被引用对象。

3.1引用传参

        引用传参指针传参类似,但理解和使用更加简单和方便,以Swap函数举例:

void Swap(int& x, int& y)
{int tmp = x;x = y;y = tmp;
}

运行结果:

        可以看到a,b交换了值,但与指针不同的是函数体里无需解引用操作,因为引用对象与被引用对象使用的是同一块内存空间,直接交换即可。

3.2引用作返回值

        为了更好的举例,在这里我们添加数据结构栈的头文件和源文件,代码详细参考:栈:数据结构中的“时间管理大师” 

        可以看到在让栈顶加10的操作中出现了报错,报错提示为StackTop(&st)不是左值,说明此时栈顶不可被修改,为右值

分析:

              

        在函数返回时,操作系统会将返回值储存在一个临时对象中,再将临时对象中的值返回,因为这个临时对象具有常性,所以栈顶不能被修改。那如何才能让这个操作合法呢?

        在这里我们将引用作返回值,并将参数优化为引用参数

// 获取栈顶元素 
STDataType& StackTop(Stack& ps)
{assert(ps._top > 0);return ps._a[ps._top - 1];
}

        此时函数栈帧销毁后,返回对象top并不是存在临时对象中,即函数栈帧销毁对返回其引用并无影响,故此时栈顶可修改。

        为了更深刻的理解引用作返回值的情况,再举一个示例:

        这里可以看到,虽然编译器并未报错,但是返回值并未加10,由于ret存在于函数栈帧中,出函数后,ret也销毁了,所以返回引用结果出现问题。

        对于引用返回,函数栈帧结束后,如果返回对象在函数栈帧中,返回引用就会出现问题,如果返回对象不在函数栈帧中,可以正常返回其引用。

4.const引用

        可以引用一个const对象,但引用也必须为const,对于普通对象也可以进行const引用,因为对象的访问权限在引用过程中只可以缩小,不能放大。

        在类型转换中的const引用:

        由于在类型转换时,操作系统会创建临时对象,临时对象具有常性,所以在转换时需要用const引用接收。

临时对象:

        所谓临时对象就是编译器需要⼀个空间暂存表达式的求值结果时临时创建的⼀个未命名的对象, C++中把这个未命名对象叫做临时对象

        临时对象在以下三种常用情况下会创建:

        1. 函数传值返回

        2.表达式运算

        3.类型转换

5.指针和引用的关系

        指针与引用在实践中相辅相成,在功能上有重叠性,但都有各自的特点,互相不可替代。

七.inline

 1.inline的定义与概念

        被inline修饰的函数叫做内联函数,在编译时C++编译器会在调用的地方展开内联函数,这样调用内联函数时就不需要创建函数栈帧了,提高了效率。

2.inline的特性

        inline适用于频繁调用的短小函数,对于递归函数,代码量较多的函数加上inline也会被编译器忽略。

        通过该段代码的汇编可以看到,在调用内联函数Swap时,并没有call指令,说明Swap函数在调用中已展开,根据右边的汇编代码可以进一步验证。

        inline不建议声明和定义分离到两个文件,分离会导致链接错误,因为inline被展开,就没有函数地址,链接时会报错。

3.inline与宏函数的比较

        先来看一段宏函数:

        对于这个宏函数,为了巩固理解,需要回答下面三个问题: 

        1.为什么要加分号?

        宏函数是在预处理时,将语句整体替换到调用处,如果加了分号,分号也会一并调换。

        2.为什么加外面的括号?

        宏函数在与其他式子作运算时需要考虑优先级的问题,加了外面的括号,保证宏函数优先级更高。

        3.为什么加里面的括号?

        a,b各自为一个表达式,加了里面的括号,保证表达式的优先运算。

        从这三个问题可以看出宏函数的实现很复杂,且很容易出错,不方便调试,所以C++中设计inline的目的就是为了替代宏函数,在提高效率的同时,更容易实现,不过与宏不同的是,inline的展开是在编译而不是预处理阶段,使其更容易调试。

八.nullptr

        NULL实际是一个,在传统的C头文件(stddef.h)中,可以看到如下代码:

#ifndef NULL#ifdef __cplusplus#define NULL 0#else#define NULL ((void *)0)#endif
#endif

        所以在C++中NULL可能会被定义为字面常量0,在下面这种情况下,与程序的初衷违背:

        这里func(NULL)的目的是调用func(int* ptr),但却由于NULL被定义成了数字常量0,调用成了func(int x),所以如果要调用func(int* ptr),还得对NULL强转类型:

        但强转类型只能让NULL强转一种类型,无法应对变量的多种类型,所以C++在这里引入了一个关键字:nullptr它可以转换成任意其他类型的指针类型。使用nullptr定义空指针可以避免类型转换的问题,因为nullptr只能被隐式地转换为指针类型,而不能被转换为整数类型。

示例:

九.总结 

        C++ 的这些基础内容,是踏上这门强大编程语言之旅的重要一步。从第一个程序的 “Hello, World!” 开始,我们逐步揭开了命名空间、输入输出、缺省参数、函数重载、引用、inline函数以及 nullptr 等关键概念的神秘面纱。这些知识相互关联,共同构成了 C++ 编程的基石。

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

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

相关文章

PHP配置虚拟主机

虚拟主机: 不是真实存在的主机, 因为一台电脑理论上讲只能作为一个网站: 事实上,一个网站是一个文件夹. 在本地开发中&#xff0c;通过虚拟主机配置可以实现多域名独立访问不同项目目录&#xff08;如 www.project1.test 和 www.project2.test&#xff09;&#xff0c;以 ”XAM…

linux安装Kafka以及windows安装Kafka和常见问题解决

目录 Linux上安装Kafka 当主题删除不了时&#xff0c;可以进入zookeeper&#xff1a; windows上安装kafka 安装Kafka需要有Zookeeper&#xff0c;或者也可以使用kafka自带的zookeeper Linux上安装Kafka 将kafka的安装包上传到/export/server目录并解压&#xff0c;重命名&…

本地YARN集群部署

请先完成HDFS的前置部署&#xff0c;部署方式可查看:本地部署HDFS集群https://blog.csdn.net/m0_73641796/article/details/145998092?spm1001.2014.3001.5502 部署说明 组件配置文件启动进程备注Hadoop HDFS需修改 需启动: NameNode作为主节点 DataNode作为从节点 Secondary…

UnrealEngine UE5 可视化 从地球观察火星 金星 土星 运动轨迹

视频参考&#xff1a;https://www.bilibili.com/video/BV1KpXSYdEdo/ 从地球观察土星的运动轨迹 从地球观察火星 轨迹 从地球观察金星的运动轨迹

【练习】【二叉树】力扣热题100 102. 二叉树的层序遍历

题目 二叉树的层序遍历 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[[3],[9,20],[15,7]] 示例…

鬼泣:项目前置设置杂项

能帮到你的话&#xff0c;就给个赞吧 &#x1f618; 文章目录 插件niagara ui render&#xff1a;在 UI 中渲染 Niagara 特效skeletal editor&#xff1a;编辑骨骼&#xff0c;调整骨骼动画motion warping&#xff1a;根据目标自动调整角色动画。animation warping&#xff1a;…

通用信息抽取大模型PP-UIE开源发布,强化零样本学习与长文本抽取能力,全面适配多场景任务

背景与简介 信息抽取&#xff08;information extraction&#xff09;是指&#xff0c;从非结构化或半结构化数据&#xff08;如自然语言文本&#xff09;中自动识别、提取并组织出结构化信息。通常包含多个子任务&#xff0c;例如&#xff1a;命名实体识别&#xff08;NER&am…

Matlab实现车牌识别

车牌识别技术作为现代智能交通系统、安防监控以及诸多车辆管理应用场景中的关键环节&#xff0c;正发挥着日益重要的作用&#xff0c;它能够自动、快速且精准地从车辆图像或视频流中提取车牌信息&#xff0c;实现车辆身份的智能化识别。 技术原理 车牌识别主要依托于图像处理、…

基于Asp.net的零食购物商城网站

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

数据结构与算法:二分答案法

前言 二分答案法是很牛逼的一种算法&#xff0c;本质思想就是猜答案&#xff0c;然后看能不能对上条件。 一、内容 1.使用条件 只有当让你输出的答案只有一个数的时候&#xff0c;且答案与给定条件之间存在单调性关系时才能使用。 2.步骤 首先&#xff0c;要先确定答案那…

Ubuntu20.04双系统安装及软件安装(十一):向日葵远程软件

Ubuntu20.04双系统安装及软件安装&#xff08;十一&#xff09;&#xff1a;向日葵远程软件 打开向日葵远程官网&#xff0c;下载图形版本&#xff1a; 在下载目录下打开终端&#xff0c;执行&#xff1a; sudo dpkg -i SunloginClient(按tab键自动补全)出现报错&#xff1a; …

快速生成viso流程图图片形式

我们在写详细设计文档的过程中总会不可避免的涉及到时序图或者流程图的绘制&#xff0c;viso这个软件大部分技术人员都会使用&#xff0c;但是想要画的好看&#xff0c;画的科学还是比较难的&#xff0c;现在我总结一套比较好的方法可以生成好看科学的viso图(图片格式)。主要思…

C++设计一:日期类Date实现

一、引言与概述 1 引言 日期操作是软件开发中的常见需求&#xff0c;如日程管理、数据统计等场景均需处理日期的比较、偏移及合法性校验。为简化此类操作&#xff0c;本文设计了一个高效且类型安全的C日期类Date。 该类通过构造函数内嵌合法性检查&#xff0c;确保对象初始状…

【网络安全】——协议逆向与频繁序列提取:从流量中解码未知协议

目录 引言 一、为什么要结合频繁序列提取&#xff1f; 二、四步融合分析法 步骤1&#xff1a;原始流量采集与预处理 步骤2&#xff1a;多粒度序列模式挖掘 层1&#xff1a;单包内字节级频繁项 层2&#xff1a;跨数据包的行为序列 步骤3&#xff1a;关键字段定位与结构假…

【PAT (Basic Level) Practice】——【数论】1013 数素数

文章目录 一【题目难度】二【题目编号】三【题目描述】四【题目示例】五【解题思路】六【最终得分】七【代码实现】八【提交结果】 一【题目难度】 乙级 二【题目编号】 1013 数素数 三【题目描述】 令 Pi 表示第 i 个素数。现任给两个正整数 M≤N≤104&#xff0c;请输出…

HCIA—IP路由静态

一、概念及作用 1、概念&#xff1a;IP路由是指在IP网络中&#xff0c;数据从源节点到目的节点所经过的路径选择和数据转发的过程。 2、作用 ①实现网络互联&#xff1a;使不同网段的设备能够相互通信&#xff0c;构建大规模的互联网络 ②优化网络拓扑&#xff1a;根据网络…

雷池WAF的为什么选择基于Docker

Docker 是一种开源的容器化平台&#xff0c;可以帮助开发人员将应用程序及其所有依赖项打包到一个称为容器的独立、可移植的环境中。Docker 的核心概念包括以下几点&#xff1a; 容器&#xff1a;Docker 使用容器来封装应用程序及其依赖项&#xff0c;使其能够在任何环境中都能…

图像分类项目2:鸟类图像分类

1 数据集处理 1.1数据集下载 数据集来源&#xff1a;kaggle&#xff0c;网址&#xff1a;https://www.kaggle.com/&#xff0c;点击进入网站&#xff0c;左侧选择Datasets。 进入后搜索栏搜索关键词bird。此时出现很多数据集可以选择&#xff0c;推荐选择第一个或者第三个。…

01_NLP基础之文本处理的基本方法

自然语言处理入门 自然语言处理&#xff08;Natural Language Processing, 简称NLP&#xff09;是计算机科学与语言学中关注于计算机与人类语言间转换的领域&#xff0c;主要目标是让机器能够理解和生成自然语言&#xff0c;这样人们可以通过语言与计算机进行更自然的互动。 …

利用opencv_python(pdf2image、poppler)将pdf每页转为图片

1、安装依赖pdf2image pip install pdf2image 运行.py报错&#xff0c;因为缺少了poppler支持。 2、安装pdf2image的依赖poppler 以上命令直接报错。 改为手工下载&#xff1a; github: Releases oschwartz10612/poppler-windows GitHub 百度网盘&#xff1a; 百度网盘…