C++入门基础篇

引言

  说到编程语言常常听到的就是C语言C++ Java 。C语言是面向过程的,C++是和Java是面向对象的,那么什么是面向对象呢?什么又是面向过程呢?C++是什么?封装、继承、多态是什么?且听我絮絮叨叨。

C++入门基础

1.命名空间

1.1 概念和作用

        在C语言中同一个作用域不能出现同名变量和函数,但在C++中可以因为C++提出了命名空间的概念,命名空间是一个单独的作用域。命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。用语言描述描述这些东西太过于晦涩直接上代码!

命名空间的格式很简单只需要一个关键字namespace + 空间的名字 + {} 。那么如何访问命名空间中的内容呢?在获取命名空间中的变量时只需空间的名字加上"::"就可以访问命名空间的中的内容。

namespace zh
{//这一是叫zh的命名空间int i = 2;void fun(){printf("这是zh\n");}
}
namespace hh
{//这是叫hh的命名空间void fun(){printf("这是hh\n");}int i = 1;
}
int mian()
{zh::fun();hh::fun();printf("%d\n", zh::i);printf("%d\n", hh::i);return 0;
}

1.2 using关键字

通过using关键字可以引入命名空间中的变量,或是直接将命名空间引入。

namespace zl
{int c = 0;
}
using namespace hh;
using zl::c;
int main()
{printf("%d\n", c);fun();return 0;
}

2.C++的输入和输出

        在C语言中的输入和输出是借助printf和scanf进行操作的,但是在C++中不使用这两函数进行输入和输出而是使用cout和cin这两个对象需要包含头文件<iostream>,在C++在包含头文件时不需要在头文件后面加.h。这里也需要大家了解到是这使用cout和cin时我们需要引用std这个命名空间这是C++标准库,C++将标准库的定义和实现都放在这个名空间内。在日常的代码练习中建议直接展开这个命名空间,这样可以方便书写不展开的话如果想使用cout就需要在cout前面加上命名空间即std::cout。(这里只是简单的使用方法不涉及底层)

cout是标准输出流对象(控制台),cin是标准输入流对象(键盘),cout和cin的优势在于自动识别数据的类型。下面这两组代码的作用都是一样的你更愿意写哪种?

int main()
{int a = 9;//1printf("%d", a);scanf("%d", &a);//2cout << a;cin >> a;return 0;
}

3.缺省参数

3.1 概念

        缺省参数我愿称其为备胎,缺省参数的作用是在定义或者声明时可以给函数的参数一个缺省值,当调用函数时不进行传参这时在编译器就会将缺省值当做默认的参数进行传参。注意在声明和定义式不能同时给缺省值。

//void func(int i = 10);
void func(int i = 10)
{cout << i << endl;
}
int main()
{func();func(1);return 0;
}

 如果放开注释就会报错

 3.2 全缺省

全缺省的意思就是函数声明或者定义时所有的参数都给缺省值

void func1(int a = 1, int b = 2, int c = 3)
{cout << a << " " << b << " " << c << endl;
}
int main()
{func1();func1(8, 9, 10);return 0;
}
3.3 半缺省

 半缺省顾名思义就是给一半的缺省参数但是需要注意的是一半的缺省参数需要从右往左给。因为只有一部分的参数有缺省参数,另一部分没有缺省参数所以在传参的时候是从左往右传参的。

void func1(int a = 1, int b = 2, int c = 3)
{cout << a << " " << b << " " << c << endl;
}
void func2(int a, int b, int c = 100, int d = 900)
{cout << a << " " << b << " " << c <<" "<< d << endl;
}
int main()
{func2(1, 2);func2(100, 200);return 0;
}

4.函数重载

        如何构成函数的重载,当函数名相同形参的类型以及个数或者类型顺序不同时就可以构成函数的重载。直接上代码

//参数类型不同
int add(int a, int b)
{cout << "add(int a, int b)" << endl;return a + b;
}
double add(double a, double b)
{cout << "add(double a, double b)" << endl;return a + b;
}
//参数个数不同
int add(int a)
{cout << "add(int a)" << endl;return a;
}
//参数的顺序不同
void print(int a, char b)
{cout <<"print(int a, char b)"<< endl;
}
void print(char b, int a)
{cout <<"char b, int a"<< endl;
}
int main()
{add(1, 2);add(1.0, 2.0);add(100);print(1, 'c');print('c', 1);
}

 为什么C++支持函数重载呢?

因为在C++中在进行编译的时候C++会对函数名进行修饰通过参数的不同或者返回值的不同对函数名进行修饰给函数名添加特殊符号等,使得链接时每个函数名都对应着不同的函数。

但是C语言没有函数名修饰的机制,函数进行编译后就直接添加到符号表中,所以无法区分同名的不同函数。

5.引用

5.1 概念

引用是对一个已经初始化过的变量重新起一个别名,这个别名指向那个变量所在的位置,编译器不会为引用开辟空间,引用和被引用的变量共用一块空间。

int main()
{int a = 0;int& b = a;cout << a << endl;cout << b << endl;return 0;
}

5.2 引用的特殊性质 

1.引用定义时必须初始化。2.一个变量可以有多个引用。3.引用一个元素后就不能引用其他元素。

int main()
{int a = 0;int& b = a;int& i = a;int c = 9;b = c;//这段代码并不会改变b的引用而是将c的值付给b,又因为b是a的应用所以改变的是a的值cout <<"b = "<< b << " "<<"i = " << i << " " << "a = " << a << endl;return 0;
}

5.3 常引用

顾名思义常引用就是对常量进行引用,但是C++中规定不能对一个常量直接进行引用,常量即为不能被修改的量。这里就需要就需要引入新的知识点,权限的放大和缩小。

权限的放大:对于一个被const修饰的对象,是不能被绑定到一个非const的引用上,当一个非const的引用绑定到const修饰的对象上时,因为被const修饰的对象是不能被修改,但是非const修饰的引用是可以随意修改的,这就导致了权限的放大(不能修改->可以随意修改),这就导致了两个概念相悖。

权限的缩小:对于一个常量对象,是可以被绑定到一个const修饰的引用上的,因为常量对象不能被修改,const修饰的引用也不能被修改,原本的引用是可以随意的修改但是加上了const修饰就将其的权限进行了缩小,在C++中权限可以被缩小但是不能被放大。

int main()
{//将一个const修饰的对象进行权限的缩小const int a = 9;const int& c = a;//将一个变量的引用用const修饰,引用本身是可以随意修改的但是加上了const就不能修改了也是权限的缩小int b = 7;const int& z = b;b = 2;//但是b变量本身是可以修改的因为b没有被const修饰return 0;
}
5.4引用的使用

C语言和C++是极度追求效率的语言,引用就能极大的提升效率。为什么说引用可以提升效率呢?下面举两个例子:1.引用做函数的参数 2.引用做函数的返回值

1.引用做为函数的参数
int Add1(int& a1, int& b1)
{return a + b;
}
int Add2(int a2, int b2)
{return a + b;
}
int main()
{int a = 9;int b = 8;Add1(a, b);Add2(a, b);return 0;
}

 上面这两段代码功能都是一样,但效率上不同。引用作为函数的参数也是就说a1是a的一个别名也就说a1是没有开辟空间的,但Add2中a2在调用的时候是需要开辟一个临时新的空间用于存储形参这个过程是需要时间的。因为计算机的计算速度非常的快,所以这两个函数调用时效率上没有区别但是如果当在调用的时候进行大量的传参呢?比如对一亿个数据进行排序呢?这样差距就体现出来了。所以在C++中经常用到引用做参数。

2.引用做函数的返回值
int& Add(int a, int b)
{int c = a + b;return c;
}
const int& Add1(int a,int b)
{return a + b;
}
int main()
{int& ret = Add(1, 2);Add(3, 4);cout << "Add(1, 2) is :" << ret << endl;return 0;
}

注:函数的返回值不是直接进行返回而是先创建一个临时变量,将临时变量的值赋给接收函数返回值的变量。临时变量是具有常性的Add1函数中返回值是cosnt类型引用的返回值,为什么要加const是因为Add1返回的是一个临时的变量具有常性所用要用const进行修饰缩小权限。

所以上述代码的结果是什么?

上述代码的结果是随机值。因为:Add函数是引用做返回值,所以返回的是一个临时的变量这个临时变量,用了一个ret引用接收ret和这个临时变量共用一个空间。这函数的栈帧结束之后这个临时变量就销毁了,临时变量销毁了所以ret就没有指向的内容了,即便在调用了一次Add因为没有用ret接收所以,这段代码运行的结果是随机值。

 5.5 引用和指针的区别

指针和引用的区别是一道经典的C++面试题。

1.从内存的角度来说指针在创建的时候是需要创建空间存储地址的,但引用不需要引用就是给原本的空间起一个别名。

2.指针可以不进行初始化,但是引用必须进行初始化。

3.有多级指针但是没有多级引用。

4.指针可以随意改变指向,但是引用不可以。

5.在sizeof中含义不同,引用返回的是引用类型的大小,而指针在32位下(4个字节)和64位下(8个字节)返回值不同。

6.引用加1即被引用的对象进行加1,指针加一是指针向后偏移一个类型的长度。

7.访问实体的方式不一样,引用编译器自动处理,指针需要解引用。

8.指针会出现野指针和为空的情况,而引用不会所以引用更加安全。

6.内联函数

6.1概念

被inline修饰的函数被称为内联函数,内联函数也是用来提高效率的。内联函数会被调用的地方进行展开,展开的目的就是不创建函数的栈帧提高运行效率。

6.2特性

1.内联是一种以空间换时间的做法,在调用的地方直接将函数展开会使目标文件会变大。

2.内联只是对编译器的一种建议,编译器可以选择不采用。假设你将一个要递归多次的函数定义为内联函数那么编译器是不会对其进行展开的。

3.内联函数不能进行函数的定义和分离,因为内联函数在编译阶段是直接被展开的,如果定义和申明分离就会导致找不到函数的地址就会导致无法连接错误。

为了实现内联展开,编译器需要在编译时看到函数的完整定义。如果内联函数的定义和声明分离,编译器在看到声明时无法进行内联展开,因为它没有函数体的具体实现。

如果内联函数的定义和声明分离,并且定义仅在一个翻译单元中可见,那么其他翻译单元在链接时将无法找到该函数的实现,导致链接错误。

7.auto关键字

7.1概念

auto关键字是自动推导类型。当定义类型比较难拼写时可以实用auto(vector的迭代器)。

int main()
{auto a = 8;//这时auto就是整形auto b = 8.9;//这是auto就是double类型//这里打印一下a b 的类型cout << typeid(a).name() << endl;cout << typeid(b).name() << endl;return 0;
}

 7.2 特性

1.auto定义的时候必须初始化,因为如果不进行初始化编译器就无法推导auto定义的变量类型。

2. auto和auto*没有什么区别,但是auto引用必须加&

因为auto是可以自动推导类型的如果初始化变量的是一个地址那么auto就会初始化为个一指针类型,但引用不能省略&因为auto无法推导。

int main()
{int a = 0;auto b = &a;auto* c = &a;auto& v = a;cout << typeid(b).name() << endl;cout << typeid(c).name() << endl;cout << typeid(v).name() << endl;return 0;
}

 3.使用auto时不能进行一行有多个变量进行定义

4.auto不能用来定义函数的参数

void dunc(auto a)//因为这使用auto在编译时无法推导出变量的类型
{cout << "dunc" << endl;
}

5.auto不能用来定义数组(C++的规定)

8.范围for的使用和语法

如果想要遍历一个数组应该怎么写?

int main()
{//常规写法int a[] = { 1,2,4,5,6,7,8 };for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++){cout << a[i] << " ";}cout << endl;//范围for写法for (auto e : a){cout << e << " ";}return 0;
}

9.空指针nullptr

 NULL是如何被定义的在C++98中NULL是一个宏被定义为(void*)指针或者0,所以这使用NULL指针时我们就会遇到麻烦。所以C++就引入了nullptr用来解决NULL的问题,相比于NULL来说nullptr更加安全。

void f(int)
{
cout<<"f(int)"<<endl;
}
void f(int*)
{
cout<<"f(int*)"<<endl;
}
int main()
{
f(0);
f(NULL);
f((int*)NULL);
return 0;
}

总结

        综上所述就是C++的一些入门知识点的讲解,这些知识点比较细碎不好理解但是这些知识点都是非常有用的在,某些特殊的场景下你会惊叹这样的语法设置非常巧妙。打个比方auto虽然看着确实方便但是好像也就一点点方便,举个栗子如果在STL容器中用来定义一些vector List这些容器的迭代器时你就感觉,auto太妙了。总之这些知识点之所以细碎是因为没有放到适合的场景下去体会,后面的博客我会带大家去好好体会其的妙用。

希望大佬们多多指点!也希望大家多多点赞、收藏、关注!

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

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

相关文章

24-9-8-读书笔记(十七)-《契诃夫文集》(三)([俄] 契诃夫 [译] 汝龙 )

文章目录 《契诃夫文集》&#xff08;三&#xff09;&#xff08;[俄] 契诃夫 [译] 汝龙 &#xff09;目录阅读笔记记录总结 《契诃夫文集》&#xff08;三&#xff09;&#xff08;[俄] 契诃夫 [译] 汝龙 &#xff09; 9月&#xff0c;好月份&#xff0c;秋高气爽&#xff0c;…

maven 编译构建可以执行的jar包

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storm…

SQL语句中in条件超过1000怎么办?

博客主页: 南来_北往 系列专栏&#xff1a;Spring Boot实战 引言 当遇到SQL语句中IN条件超过1000个的情况时&#xff0c;可以采取以下几种策略来有效处理这一问题&#xff1a; 使用临时表&#xff1a;将IN列表中的值存储在临时表中&#xff0c;并将该临时表与查询表进行J…

初识redis(String,Hash,List,Set,SortedSet)

认识NoSql sql关系型数据库 nosql非关系型数据库 nosql具有非结构化&#xff0c;Key/Value&#xff0c;Document&#xff0c;Draph 无关联的&#xff0c;非sql&#xff0c;BASE&#xff08;原子性&#xff0c;持久性&#xff0c;一致性&#xff0c;隔离性&#xff09; 认识r…

数组与贪心算法——179、56、57、228(2简2中)

179. 最大数&#xff08;简单&#xff09; 给定一组非负整数 nums&#xff0c;重新排列每个数的顺序&#xff08;每个数不可拆分&#xff09;使之组成一个最大的整数。 注意&#xff1a;输出结果可能非常大&#xff0c;所以你需要返回一个字符串而不是整数。 解法一、自定义比较…

Linux-RPM与YUM

目录 前言&#xff1a; rpm包的管理 rpm包的简单查询指令 ​编辑 rpm包名的基本格式 rpm包名基本格式 ​编辑 卸载rpm包 细节问题 安装rpm包 yum yum的基本指令 安装指定的yum包 yum报错 问题描述&#xff1a; 解决方法&#xff1a; 前言&#xff1a; Linux操…

模型压缩之剪枝

&#xff08;1&#xff09;通道选择 这里要先解释一下&#xff1a; &#xff08;1&#xff09;通道剪枝 那我们实际做法不是上面直接对所有层都添加L1正则项&#xff0c;而是仅仅对BN层权重添加L1正则项。通道剪枝具体步骤如下&#xff1a; 1.BN层权重添加L1正则项&#xf…

还不懂BIO,NIO,AIO吗

BIO&#xff08;Blocking I/O&#xff09;、NIO&#xff08;Non-blocking I/O&#xff09;和 AIO&#xff08;Asynchronous I/O&#xff09;是 Java 中三种不同的 I/O 模型&#xff0c;主要用于处理输入 / 输出操作。 一、BIO&#xff08;Blocking I/O&#xff09; 定义与工作原…

ANSA联合ABAQS基于梁单元的螺栓预紧力分析实例

1、在螺栓孔之间创建一个模拟螺栓 ABAQUS界面→AUXILIARIES→bolt→分鳖选择上下两圈节点,这样在螺栓孔中间就会生成一个梁单元。 中键确定,因为螺杆使用的是变形体,所以接下来需要为其创建一个属性: 单击ok,完成虚拟螺栓的创建,该螺栓两端是刚性MPC,中间是弹性的梁单元…

美畅物联丨科技赋能校车安全:智慧监控管理系统的创新应用

1、背景 1.1应用需求 孩子&#xff0c;作为国家未来的希望之星和民族发展的潜力所在&#xff0c;其安全与健康向来都是社会瞩目的核心要点。校车&#xff0c;作为孩子们日常出行的关键交通载体&#xff0c;其安全性更是时刻牵动着每一个家庭的敏感神经。然而&#xff0c;不可…

利用TCP编程实现FTP功能

模拟FTP核心原理&#xff1a;客户端连接服务器后&#xff0c;向服务器发送一个文件。文件名可以通过参数指定&#xff0c;服务器端接收客户端传来的文件&#xff08;文件名随意&#xff09;&#xff0c;如果文件不存在自动创建文件&#xff0c;如果文件存在&#xff0c;那么清空…

828华为云征文|使用sysbench对Mysql应用加速测评

文章目录 ❀前言❀测试环境准备❀测试工具选择❀测试工具安装❀mysql配置❀未开启Mysql加速测试❀开启Mysql加速测试❀总结 ❀前言 大家好&#xff0c;我是早九晚十二。 昨天有梳理一篇关于华为云最新推出的云服务器产品Flexus云服务器X。当时有说过&#xff0c;这次的华为云F…

【科研小白系列】使用screen创建虚拟终端,实现本地关机后服务器仍然跑模型

博主简介&#xff1a;努力学习的22级计算机科学与技术本科生一枚&#x1f338;博主主页&#xff1a; 是瑶瑶子啦往期回顾&#xff1a; 【科研小白系列】模型训练已经停止(强行中断)了&#xff0c;可GPU不释放显存&#xff0c;如何解决&#xff1f; 每日一言&#x1f33c;: “生…

k8s网络

pod 网络 在K8S集群里&#xff0c;多个节点上的Pod相互通信&#xff0c;要通过网络插件来完成&#xff0c;比如Calico网络插件。 使用kubeadm初始化K8S集群时&#xff0c;有指定一个参数–pod-network-cidr10.18.0.0/16 它用来定义Pod的网段。 而我们在配置Calico的时候&#…

Trm理论 2(Word2Vec)

神经网络模型&#xff08;NNLM&#xff09;和Word2Vec NNLM模型是上次说过的模型&#xff0c;其目的是为了预测下一个词。 softmax(w2tanh(w1x b1)b2) 会得到一个副产品词向量 而Word2Vue就是专门求词向量的模型 softmax(w2*(w1*x b1)b2) Word2Vec softmax(w2*(w1*x b1)b…

jmeter性能测试HTML测试报告生成详解

作用&#xff1a;jmeter支持生成HTML测试报告&#xff0c;方便查看测试计划中获得图表和统计信息 命令&#xff1a; jmeter -n -t [jmx file] -l [result file] -e -o [html report folder] 示例&#xff1a;jmeter -n -t login.jmx -l result.jtl -e -o ./report jmx文件&a…

Gmsh:一个开源的三维有限元网格生成工具

Gmsh 是一个开源的三维有限元网格生成工具,主要用于在计算流体力学(CFD)和有限元分析(FEA)中生成复杂几何体的网格。它具有强大的几何建模、网格生成、求解器接口和后处理功能。Gmsh 适用于多种物理领域的模拟,包括流体力学、结构分析、电磁学等。 下载地址:https://gm…

【HarmonyOS】- 内存优化

文章目录 知识回顾前言源码分析1. onMemoryLevel2. 使用LRUCache优化ArkTS内存原理介绍3. 使用生命周期管理优化ArkTS内存4. 使用purgeable优化C++内存拓展知识1. Purgeable Memory总结知识回顾 前言 当应用程序占用过多内存时,系统可能会频繁进行内存回收和重新分配,导致应…

Java中Date类型上的注解

在日常开发中&#xff0c;涉及到日期时间类型Date和常用的注解DateTimeFormat和JsonFormat java.util.Date; org.springframework.format.annotation.DateTimeFormat; com.fasterxml.jackson.annotation.JsonFormat; 一 Date类型字段不使用注解 Data AllArgsConstructor N…

开源还是封闭?人工智能的两难选择

这篇文章于 2024 年 7 月 29 日首次出现在 The New Stack 上。人工智能正处于软件行业的完美风暴中&#xff0c;现在马克扎克伯格 &#xff08;Mark Zuckerberg&#xff09; 正在呼吁开源 AI。 关于如何控制 AI 的三个强大观点正在发生碰撞&#xff1a; 1 . 所有 AI 都应该是开…