c++ 基础(新手入门必看)

news2024/10/6 2:31:15

C++基础讲解,用于C语言向C++的衔接

文章目录

  • 命名空间
  • C++输入输出
  • 缺省参数
  • 函数重载
  • 引用
  • 内联函数
  • auto关键字
  • 基于范围for循环
  • 指针空值 -- nullptr

命名空间

如果你以前看到过C++的程序,那么你大概率会看到这样一行代码
在这里插入图片描述
这行代码就用到了命名空间的知识,using就是使用的意思,namespace就是命名空间,std就是这个命名空间的名字。
C++的命名空间,顾名思义,就是在某一空间内对一些类型(变量,常量,结构体,函数等)进行命名。
在这里我进行示范,写下一个命名空间
在这里插入图片描述
注意这里命名空间内的两个变量是全局变量,而不是局部变量。这里我就不得不提一下,只有定义在函数内的变量才是局部变量,为什么?因为局部变量存储在栈区,而函数的调用会创建栈帧,函数结束时栈帧会销毁,并且局部变量随之销毁。
而命名空间内的变量是全局变量,它们存储在静态区。并且我顺便提一下,局部变量存储在栈区,全局变量存储在静态区,动态内存开辟的空间存储在堆区。
还有就是我们头文件里的变量属于什么?在预处理时头文件就被展开了,所以头文件内的变量其实也属于全局变量。
并且编译器默认的查找规则是:先在局部找,再到全局找。并且如果有了命名空间,直接去指定的命名空间内找,当命名空间内也找不到这个这个名字的话,就会报错,而不会继续去别的地方找。
命名空间如何使用?
在这里插入图片描述
这时候我们发现我们用不了a,刚才不是说a是全局变量吗,这里为什么用不了?原因是命名空间就像无形的一堵墙一样,它把它内部的变量全都关住了,别人根本就找不到它。
如果要想使用,就必须加上名称空间标示符。
在这里插入图片描述
但是,如果我们要大量地使用a这个变量的话,每次都加上名称空间标识符岂不是很麻烦?
所以我们也有其他的方法
在这里插入图片描述
如果我们不只是频繁地使用这个命名空间中的一个变量,而是频繁地使用其他变量的话,也可以这样表示。

在这里插入图片描述
我们明白了这个之后,再解释解释经常看到的那个命名空间。
在这里插入图片描述
std 是C++官方库内定义的命名空间。C++官方库内有许多文件,每个文件内的命名空间都为std,这样并不会导致冲突,因为不同位置的同名命名空间会合并为同一个命名空间。
上面那条语句的作用,相当于把std展开,把它里面所有的东西都暴露出来,这样使用就很方面了。
但是这样又有一些不足,我们在日常写一些小程序的时候这样写没什么问题,但是项目里不要这么写,容易引起和自己定义的变量引起冲突。
我们在项目里面可以进行这样使用。
在这里插入图片描述
把常见的名字这样单独拿出来,在自己起名字的时候避开这些常见的就可以了。

另外,命名空间也是可以嵌套的,比如:
在这里插入图片描述

总结:通常来说,命名空间是唯一识别的一套文字,这样当相同的名字却来自不同的地方的时候就不会含糊不清了。也就是说,命名空间的使用可以避免命名的冲突。同时,命名空间的展开又可以分为局部展开,全部展开,也可以不展开,在使用的时候加上标识符即可。

C++输入输出

C++的输入输出我们作为新手不需要过多的了解,只要会使用即可。
在这里插入图片描述
cin相当于C语言的输入函数,cout相当于C语言的输出函数。与C语言中输入输出函数不同的是,cin和cout可以自动识别变量的类型。

缺省参数

定义:缺省参数是在函数声明或者定义时为函数的参数指定一个缺省值,在函数调用时如果没有指定的实参则形参的值为缺省值,否则就为指定的实参。
在这里插入图片描述
当函数的参数中有多个参数具有缺省值时,则有不同的传参方法。

在这里插入图片描述
并且,传参是连续的,必须从左到右传参,不能只给c传参而不给a和b传参。
注意,函数的声明和定义中不能同时出现缺省参数,防止出现声明和定义中缺省参数不一样的尴尬局面。如果函数同时有声明和定义的话,要把缺省参数放在声明中。

函数重载

定义:函数重载是函数的一种特殊情况,C++允许在同一空间内定义功能类似且名字相同的函数,这些函数的参数(参数类型,参数个数,参数顺序)不同,常用来处理功能类似但数据类型不同的问题。

在这里插入图片描述
就像这样,我们定义两个add函数,实现函数重载,就不用在意我们要相加的两个数是整数还是浮点数了。

但是,函数重载不能与缺省参数结合起来使用,就像这样。
在这里插入图片描述
你不传参进去,编译器不知道你想调用哪一个函数。

为什么C语言不支持函数重载,而C++可以?C++存在名字修饰!
C语言编译之后,函数名不会发生变化。而C++编译之后,编译器用根据函数的参数类型对编译器进行修饰,这就是名字修饰。

为什么同名函数的参数相同而只有返回值不同不会进行函数重载?
这并不是因为名字修饰时不会带上返回值的类型,而是因为在调用函数的时候具有二义性,编译器不知道函数要返回什么类型的值。

引用

引用就相当于给变量取别名,使得变量在同一空间内有多个名字。
在这里插入图片描述
你对引用操作,和对引用的实体操作的是一样的。
在这里插入图片描述

并且这和指针不一样,指针是指向a这个变量的地址。而引用就是引用的实体,它们两个是一样的。
对引用和引用的实体取地址你就明白了。
在这里插入图片描述
引用的特性:

  1. 引用必须进行初始化
  2. 一个变量可以有多个引用
  3. 一个引用一旦引用了一个实体,就不能引用其他实体了

Java和Python的引用是可以改的,但C++不可以。
从这方面看,C++的引用不可能会代替指针。就比如在写一个链表的时候,如果要遍历一个链表,我们会用到一个链表节点的指针,并且不断改变这个指针的指向,如果用引用的话,就不能实现这个功能了。

引用的使用场景:

  1. 作参数
    在这里插入图片描述
    这里也可以用指针,但是用引用效率会更高一些。

  2. 作返回值
    引用是可以作为返回值的,并且效率比较高,但只适用于特定的情况下
    要明白这个道理,首先我我们要明白传值返回和传引用返回的区别

在这里插入图片描述
这样是可以的,为什么可以?int类型的变量用static修饰之后会存储在静态区,而不会存储在栈区,这样在函数的栈帧销毁之后n这个变量就不会随之销毁了,这个时候n还是存在的,我们把它的值拷贝给ret当然是可以的。

在这里插入图片描述
这样也是可以,虽然在函数栈帧销毁之后存储在函数栈帧的n也随之销毁,但是在销毁之前会把n的值保存起来,具体保存在哪里需要看变量的大小,如果变量较小就会保存在寄存器中,如果变量较大就会保存在上一层函数的栈帧中。所以,这是可以的,虽然n不存在了,但是n的值已经被保存下来了,我们可以将保存的这个值拷贝给ret。

在这里插入图片描述
这样呢?我们将引用作为返回值,返回的就不是n了,而是n的引用。此时和第一种情况一样,n仍然是存在的,所以n的引用的值和n是相同的,我们用ret是可以得到n的值了。

在这里插入图片描述
这样就会出现问题了,编译时虽然可以通过,并且ret的值也可能是我们想要的,但是存在一些风险。
在返回引用时可就不会像第二种情况临时拷贝一份n的值并保存起来了,而是直接返回,不关心n是否被销毁。这样的话,n已经被销毁,再返回n的引用的,我们可以根据引用来找到n,但是得到的值是不确定的。
首先我们应该好好想想,n被销毁了,也就是说保存n的空间被销毁了。
空间被销毁了,空间还存在吗?存在!只是没有了这个空间的使用权了而已。
空间被销毁了,我们还能访问那?可以!只是访问得到的值不确定了,这块空间上的值,可能还是原来的值,也可能值是随机的,也可能空间被别人使用了,从而值被修改了。

如果你不明白,我给你打一个比方?
空间的申请和释放就像住酒店,你申请一块空间就像开一个房间,你释放这块空间就像退房。假如你退房之后,悄悄地赔了一把这个房间的钥匙,然后你仍然可以进入这个房间,虽然这是非法的。但是,如果你原来在房间内放了一个苹果,你再次进入这个房间之后,这个苹果的情况你确定吗?它可能还是原来的苹果,也可能被别人咬了一口,还有可能这个苹果被换成了梨。
那你空间释放之后,你再访问这个空间的变量,就像你再次非法进入了这个房间,虽然你能访问(虽然你能进去),但是得到的值可能是原来的值(苹果还是原来的苹果),也可能值不确定了(苹果被咬了一口),还有可能这个值被其他的值替换了(苹果被换成了梨)
在这里插入图片描述
你也可以看下这种情况,如果你返回引用,并且用ret这个引用来接收,那么ret就是n的引用,我们打印ret的值,ret可能是原来的值,但是之后调用test2这个函数之后,原来n的空间存的1就被100覆盖了,这个时候ret的值也就变为100了。

说了这么多,我就是要说明传引用返回在一些情况下是不适用的。

只有变量在被static修饰的时候传引用返回才是可以的,这个时候我们就相当于是把苹果放在了酒店的前台,不管我们上面时候去拿这个苹果,它也都是原来的苹果。
在这里插入图片描述
并且,当大量调用这个函数时,用传引用返回是最好的,因为它的效率比较高。
那么,关于传引用返回的一些细节就介绍到这里。

关于引用,也有一些奇妙的东西,下面我们一起来看一下。

引用和指针一样,在赋值时,权限可以缩小,但不能放大。
在这里插入图片描述
当变量是只读时,引用的权限也只是只读。

很多时候,用引用作参数都将引用设为了只读,可以避免权限的放大。
在这里插入图片描述
但是,有些要对变量进行修改的函数就不能作为const了,比如swap。

并且用const修饰的实体可以为常量。
在这里插入图片描述

再来看一些好玩的东西。

我们知道,类型转换的时候会产生临时变量
在这里插入图片描述
不管是加括号的强制类型转换,还是隐形转换,都是产生了一个转换后的临时变量,然后将这个临时变量赋值给其他变量。

并且临时变量具有常性,是不可以修改的。如果用要引用的实体和引用不同,那么引用的实体也会产生一个转换后的临时变量,然后将它赋值给引用,同时因为临时变量不可修改,引用必须要加const来修饰。
在这里插入图片描述

同时,如果要用引用接收函数的返回值也要加const修饰。刚才我们提到,返回值是临时拷贝了一份,然后再赋值给接收的变量,刚才我们又说临时变量是不可修改的,所以用来接收返回值的引用也要加const修饰。
在这里插入图片描述

引用占空间吗?引用在语法上面,它只是一个名字,是不占空间的。但是在底层实现上,引用是用指针实现的,它是占有一定空间的。

引用和指针的对比:

  1. 引用在概念上是一个变量的别名,而指针是存储变量的地址。
  2. 引用必须初识化,而指针不用
  3. 引用在引用一个实体之后,就不能引用其他实体,但指针可以改变指向。
  4. 没有NULL引用,但有NULL指针
  5. 使用sizeof,括号内是引用得到引用的实体的大小,括号内是指针得到存储地址的大小。
  6. 引用自加则实体也会自加,而指针自加表示则向后偏移一个类型的大小
  7. 有多级指针,但是没有多级引用
  8. 引用的解引用编译器会处理,而指针的解引用需要程序员来处理
  9. 引用比指针更加安全

内联函数

定义:以inline关键字修饰的函数是内联函数,在如果调用该内联函数,编译时会直接将函数体展开在程序中,而不会建立栈帧,从而提升了程序运行的效率,是一种以空间换时间的做法
若要大量使用某个函数,同时又不想建立栈帧,C语言可以使用宏来进行处理。
但是宏是有很多确定的:

  1. 宏不可以进行调试
  2. 宏没有类型安全的检查
  3. 宏会因为优先级的问题而产生许多不可预料的结果

基于这个方面,C++的方案是内联函数。
在这里插入图片描述
这样的话,就既有了函数的优点,又具有了宏的优点。

不是所有的函数都适合内联,比如递归函数和比较长的函数就不适合,一般内联函数都是在十行以内。

关于内联函数,我们需要知道以下几点:

  1. inline是一种以时间换空间的做法,若使用内联函数,在编译阶段就会将该调用内联函数的地方替换为函数体,就不需要进行函数栈帧的创建和销毁了。这样做的缺点是会使目标文件变大,优点是不需要进行函数栈帧的创建和销毁,大大提高了程序的运行效率
  2. 内联函数的使用,是向编译器发出了一个使用的建议,而具体使用不使用还是取决于编译器,如果内联函数规模较大(就是比较长,具体标准是多少取决于编译器),或者用到了递归,又或者是频繁地调用,编译器就会忽略这个内联的特性。为什么会这样?防止代码膨胀!
  3. 如果使用内联函数,定义和声明不能分离在不同文件中,分离会导致链接错误。因为在编译阶段内联函数就被展开了,地址也就不存在了,链接也就找不到了。

auto关键字

在这里插入图片描述
使用auto声明指针类型时,auto和auto*没有区别,但是使用auto声明引用类型必须使用auto&。

在这里插入图片描述
auto不能作为函数参数,并且auto也不能声明数组。

基于范围for循环

它就是用来更方便地遍历一个数组
在这里插入图片描述

这样写没有效果,不能真的将数组元素乘2,为什么?
在这里插入图片描述
因为x只是数组元素的临时拷贝!

正确的写法是这样的
在这里插入图片描述
并且这里我们不能用指针,因为我们每次取到的是每个元素的值,而不是每个元素的地址

在这里插入图片描述
就比如你在这个函数内对arr进行sizeof,得到的只是arr这个数组首元素地址的大小而已。

指针空值 – nullptr

在C++中,空指针有两种表示方式。
在这里插入图片描述
并且NULL的值就是0
在这里插入图片描述
这是因为
在这里插入图片描述可以看到,NULL可能被定义为字面常量0,或者被定义为无类型指针(void*)的常量。不论采取何种定义,在使用空值的指针时,都不可避免的会遇到一些麻烦,比如:
在这里插入图片描述
这样就存在二义性了,程序本意是想通过f(NULL)调用指针版本的f(int*)函数,但是由于NULL被定义成0,因此与程序的初衷相悖。
在C++98中,字面常量0既可以是一个整形数字,也可以是无类型的指针(void*)常量,但是编译器默认情况下将其看成是一个整形常量,如果要将其按照指针方式来使用,必须对其进行强转(void *)0。

语言的更新有一个原则,就是不变动原来的语法规则(随意变动原来的语法规则会导致原来的许多程序崩溃),而是加入新的特性。

所以,在C++11中,我们引入nullptr这个关键字。

注意:

  1. 在使用nullptr表示指针空值时,不需要包含头文件,因为nullptr是C++11作为新关键字引入的。
  2. 在C++11中,sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。
  3. 为了提高代码的健壮性,在后续表示指针空值时建议最好使用nullptr。

好啦,看到这里,你已经走出了C++的新手村,继续向后学习吧!

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

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

相关文章

QT 系统学习 day06 ,摄像头,语音识别(语音转文字,文字转语音,Qt 的人脸识别系统),

1.调用摄像头&#xff0c;拍照&#xff0c;存储照片 1.摄像头文件 /******* 摄像头相关类 *****/ #include <QCamera> /*** 摄像头类 ***/ #include <QCameraInfo> /*** 系统摄像头属性类 ***/ #include <QCameraImageCapture> /*** 用于记录摄像头数据的类…

C语言入门(一)——程序的基本概念

程序的基本概念 程序和编程语言 自然语言和形式语言 程序的调试 第一个程序 程序的基本概念 程序和编程语言 1.程序 程序&#xff08;Program&#xff09;告诉计算机应如何完成一个计算任务&#xff0c;这里的计算可以是数学运算&#xff0c;比如解方 程&#xff0c;也可…

Centos7下安装PostgreSQL14及其基本命令使用

MySQL关系型数据库目前算是互联网公司使用最多的。前两天看到一个推文&#xff0c;相对比国内使用MySQL&#xff0c;PostgreSQL在国内的普及貌似不高&#xff1f;国外像网络电话公司Skype公司等在大量使用PostgreSQL 作为互联网从业者&#xff0c;保持学习是必须的。开始学习Po…

小甲鱼C语言【课后笔记第一章——打印(printf)

目录 1、“打印”就是“输出”的意思 2、使用 GCC 编译程序&#xff1a;gcc 源代码 -o 可执行文件。 3、printf 是格式化输出函数 a、函数概要 b、函数原型 c、参数分析 d、返回值 e、演示 4. 转义字符 5. 反斜杠的奥义 6、课后习题&#xff08;编程题&#xff09; 1、…

性能工具之JMeter模拟多IP地址访问

文章目录一、前言二、前置条件三、操作步骤一、前言 今天一同事在压测时提到怎么用 JMeter 里虚拟多个 IP 来发送请求&#xff0c;我想了一下以前用LR时用过虚拟ip地址&#xff0c;JMeter 还没有使用过。想着原理应该是相通的&#xff0c;既然 LR 都能支持的话&#xff0c;那 …

多线程学习笔记(四)-- 常见类及使用

1. thread的方法 Thread.sleep()&#xff1a;占用cpu资源 Thread.yeild()&#xff1a;当前线程让渡cpu资源&#xff0c;大家竞争&#xff0c;也有再抢到cpu的机会 t1.join()&#xff1a;在t2线程中&#xff0c;调用t1.join()&#xff0c;是等待t1执行完成 2. 线程状态 3. sy…

力扣(LeetCode)142. 环形链表 II(C++)

哈希表 最直观的思想&#xff0c;哈希表记录遍历的结点&#xff0c;如果结点重复出现&#xff0c;则有环。如果遍历到空结点&#xff0c;无环。 class Solution { public:ListNode *detectCycle(ListNode *head) {unordered_set<ListNode *> ad;auto tail head;while(…

java计算机毕业设计ssm医患交流平台93xzr(附源码、数据库)

java计算机毕业设计ssm医患交流平台93xzr&#xff08;附源码、数据库&#xff09; 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。…

用Excel自带图表插入带分类变量的箱形图(单坐标轴并列箱)

箱型图主要用来观察一个或多个类别下&#xff0c;数值型变量的分位数及离群值的特征和分布&#xff0c;以及在一定程度上观察到偏度和峰度的状态。网上有一些自己计算分位数来绘制箱型图的方法&#xff0c;但一方面是没有直接使用excel自带的箱型图好看和功能全面&#xff0c;二…

qq群聊机器人接入ChatGPT-简介和源码

qq群聊机器人接入ChatGPT 最近 ChatGPT 很火&#xff0c;也注册了账号玩了玩&#xff0c;确实灰常强大。但是也有的小伙伴可能没办法注册账号&#xff0c;我就想着把qq群机器人接入ChatGPT。 过程还是比较简单顺利的。下面简单介绍一下 直接跳过介绍&#xff0c;查项目代码 1…

绘制金字塔-第10届蓝桥杯Scratch选拔赛真题精选

[导读]&#xff1a;超平老师计划推出Scratch蓝桥杯真题解析100讲&#xff0c;这是超平老师解读Scratch蓝桥真题系列的第100讲。 蓝桥杯选拔赛每一届都要举行4~5次&#xff0c;和省赛、国赛相比&#xff0c;题目要简单不少&#xff0c;再加上篇幅有限&#xff0c;因此我精挑细选…

基于java(springboot)校园新闻管理系统源码(java毕业设计)

基于java(springboot)校园新闻管理系统 校园新闻管理系统是基于java编程语言&#xff0c;MySQL数据库&#xff0c;和springboot框架&#xff0c;用idea开发工具开发的设计&#xff0c;本设计分为学生用户&#xff0c;管理员两个角色&#xff0c; 学生的主要功能是可以注册登陆…

Cpolar实现虚拟机内网穿透,搭建私人云服务器

Cpolar实现虚拟机内网穿透,搭建私人云服务器 一、Cpolar功能介绍 Cpolar官网 Cpolar是一个安全的内网穿透的服务&#xff0c;可以将内网下的本地服务器通过安全隧道暴漏给公网。允许公网用户可以正常访问内网服务&#xff0c;是一款免费的内网穿透软件。只需要一行命令&#…

Python小炼(1):初识Python

"也许对我来说&#xff0c;太多拘束可能" 本篇的主要内容,针对的是一些常见的语法&#xff0c;在python中是怎样表示的&#xff0c;例如,python变量如何定义、选择、循环、判断结构是如何表示的&#xff1f;python函 数定义是怎么定义的…… ----前言 一、认识pyt…

无需代理及注册在VsCode中使用ChatGPT

无需代理及注册在VsCode中使用ChatGPT 安装 要安装扩展&#xff0c;请按照下列步骤操作&#xff1a; 1.打开 Visual Studio Code 2.单击左侧栏中的扩展程序图标 3.搜索"ChatGPT中文版" 4.点击安装按钮安装扩展 5.重启VSCode 用法 开始使用 在编辑器中右键触发…

【LeetCode每日一题:1691. 堆叠长方体的最大高度~~~排序+贪心】

题目描述 给你 n 个长方体 cuboids &#xff0c;其中第 i 个长方体的长宽高表示为 cuboids[i] [widthi, lengthi, heighti]&#xff08;下标从 0 开始&#xff09;。请你从 cuboids 选出一个 子集 &#xff0c;并将它们堆叠起来。 如果 widthi < widthj 且 lengthi < …

Java学习笔记6.3.3 文件操作 - 对象序列化与反序列化

文章目录零、本讲学习目标一、对象序列化与反序列化&#xff08;一&#xff09;对象序列化与反序列化概念&#xff08;二&#xff09;对象序列化与反序列化示意图&#xff08;三&#xff09;实际开发中序列化和反序列化的场景&#xff08;四&#xff09;实现对象序列化的两种方…

26岁,干了三年测试,月薪才12k,能跳槽找到一个更高薪资的工作吗?

在我们的身边&#xff0c;存在一个普遍现象&#xff1a;很多人从事软件测试岗&#xff0c;不计其数&#xff0c;经历的心酸难与外人道也。可是技术确难以提升、止步不前&#xff0c;薪资也只能看着别人水涨船高&#xff0c;自己却没有什么起色。 虽然在公司里属于不可缺少的一…

计算机网络:数据链路层

数据链路层 数据链路层主要处理单个链路上如何传输数据&#xff0c;并且向网络层向上提供服务 1. 数据链路层概述 1.1 术语介绍 主机拥有全部的计算机网络结构&#xff0c;路由器只有一部分 各个路由器之间由物理层连接 红线为发送的信息 1.2 数据链路层的三个重要问题 封装…

职业危机:从无到有,从弱到强;反思再反思和应对措施

一、写在开头 每天每周不写点东西&#xff0c;不把脑中的疑惑写明白&#xff0c;就感觉不到每天的进步。 每天没进步&#xff0c;这北漂生活&#xff0c;何时是个头啊。 可以北漂10年&#xff0c;也可以20年&#xff0c;但不可能是一辈子。 因为我不是北京人呐。 二、持续转…