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;
	//1
	printf("%d", a);
	scanf("%d", &a);
	//2
	cout << 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太妙了。总之这些知识点之所以细碎是因为没有放到适合的场景下去体会,后面的博客我会带大家去好好体会其的妙用。

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

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

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

相关文章

SpringBoot OAuth2自定义登陆/授权页

背景 5 月份的时候&#xff0c;我实践并整理了一篇博客&#xff1a;SpringBoot搭建OAuth2&#xff0c;该博客完成之后&#xff0c;很长一段时间里我都有种意犹未尽的感觉。诚然&#xff0c;我把OAuth2搭起来了&#xff0c;各种场景的用例也跑通了&#xff0c;甚至源码也看了&am…

《花100块做个摸鱼小网站! 》第六篇—将小网站部署到云服务器上

⭐️基础链接导航⭐️ 服务器 → ☁️ 阿里云活动地址 看样例 → &#x1f41f; 摸鱼小网站地址 学代码 → &#x1f4bb; 源码库地址 一、前言 到这一篇我们终于把环境搭好&#xff0c;也做好了几个热搜小组件&#xff0c;为了让我们方便展示成果或者方便自己摸鱼&#xff0c…

2024最新!Facebook手机版和网页版改名教程!

Facebook作为全球最大的社交平台之一&#xff0c;允许用户自定义名字和昵称。在Facebook更新姓名可以帮助您更好的展现账号形象。本文将为您提供详细的步骤指导&#xff0c;帮助您在手机APP和网页版上轻松完成Facebook改名操作。 Facebook手机版改名 打开Facebook APP并登录账号…

DataGridView用法合集【精品】

目录 1.当前的单元格属性取得、变更 2.DataGridView编辑属性 3.DataGridView最下面一列新追加行非表示 4.判断当前选中行是否为新追加的行 5. DataGridView删除行可否设定 6. DataGridView行列不表示和删除 7. DataGridView行列宽度高度设置为不能编辑 8. DataGridView行…

SQL进阶技巧:如何利用SQL解决趣味赛马问题?| 非等值关联匹配问题

目录 0 问题描述 1 数据准备 2 问题分析 方法一:先分后合思想 方法2:非等值关联匹配 3 小结 0 问题描述 有一张赛马记录表,如下所示: create table RacingResults ( trace_id char(3) not null,race_date date not null, race_nbr int not null,win_name char(30) n…

【北京迅为】《STM32MP157开发板使用手册》-第十四章 QtE5.12应用开发

iTOP-STM32MP157开发板采用ST推出的双核cortex-A7单核cortex-M4异构处理器&#xff0c;既可用Linux、又可以用于STM32单片机开发。开发板采用核心板底板结构&#xff0c;主频650M、1G内存、8G存储&#xff0c;核心板采用工业级板对板连接器&#xff0c;高可靠&#xff0c;牢固耐…

企业品牌声量统计怎么做?有没有什么工具?

企业在进行社交媒体推广宣传的过程中&#xff0c;通常需要关注品牌声量&#xff0c;借此衡量品牌传播效果、进行投放营销复盘等。也可以辅助下一步品牌策略的制定。那品牌声量是什么&#xff0c;怎么去统计这个品牌声量数据呢&#xff1f; 品牌声量是什么&#xff1f; 简单来…

mysql笔记3(数据库、表和数据的基础操作)

文章目录 一、数据库的基础操作1. 显示所有的仓库(数据库)2. 创建数据库注意(命名规范)&#xff1a; 3. 删除数据库4. 查看创建数据库的SQL5. 创建数据库时跟随字符编码6. 修改数据库的字符编码 二、表的基础操作1. 引入表的思维2. 引用数据库3. 查看该数据库下面的表4. 创建表…

全网最适合入门的面向对象编程教程:46 Python函数方法与接口-函数与事件驱动框架

全网最适合入门的面向对象编程教程&#xff1a;46 Python 函数方法与接口-函数与事件驱动框架 摘要&#xff1a; 函数是 Python 中的一等公民,是一种可重用的代码块,用于封装特定的逻辑&#xff1b;事件驱动框架是一种编程模式&#xff0c;它将程序的控制流转移给外部事件,如用…

vscode docker debug python

1. 安装Vscode插件 ”Docker“”Dev Containers““Remote - ssh” 2. 进入Docker环境 点击左侧 Docker图标&#xff0c;选择Containers 对容器进行右键启动 生成新页面直接进行选择文件路径即可&#xff0c;之后得操作均在容器内进行

6.1排序——插入排序与希尔排序

本篇博客来梳理两种常见排序算法&#xff1a;插入排序与希尔排序 常见的排序算法如图 写排序算法的原则&#xff1a;先写单趟&#xff0c;再写整体 一、直接插入排序 1&#xff0e;算法思想 先假定第一个数据有序&#xff0c;把第二个数据插入&#xff1b;再假设前两个数据…

读取、写入、生成txt文本文档详解——C#学习笔记

一、4中写入文本的方式&#xff1a; //①表示清空 txt StreamWriter mytxt1 new StreamWriter("D:\\1清空.txt"); string t1 ""; mytxt1.Write(t1); mytxt1.Close(); //②表示向txt写入文本 StreamWriter mytxt2 new StreamWriter("D:…

不到200行代码,一键写出简单贪吃蛇网页游戏!附详细代码!快来看看吧!

​哈喽大家好&#xff0c;这里是大白百宝阁&#xff0c;每天分享一段小代码~ 今天要分享的是&#xff0c;不到200行代码&#xff0c;制作html版贪吃蛇&#xff0c;效果如下&#xff1a; 游戏结束后&#xff0c;还会显示&#xff1a; 代码如下&#xff1a; <!DOCTYPE html&g…

GitHub图床

GitHub图床 文章目录 GitHub图床图床介绍Github访问GitHub手动修改hostsgithub520 加速器创建账户创建仓库创建token PicGoTypora 图床介绍 图床 存放图片的地方 为什么设置图床呢 在我认识图床之前, 有一个问题 [^放在typora上面的图片, 其实是一个链接, 并且将图片存放在本地…

Java之枚举

目录 枚举 引入 定义 代码示例 常用方法 代码示例 枚举的优缺点 枚举和反射 面试题 枚举 引入 枚举是在JDK1.5以后引入的。主要用途是&#xff1a;将一组常量组织起来&#xff0c;在这之前表示一组常量通常使用定义常量的方式&#xff1a; publicstaticintfinalRED1;…

树莓派通过串口驱动SU-03T语音模块

树莓派通过串口驱动SU-03T语音模块 文章目录 树莓派通过串口驱动SU-03T语音模块一、SU-03T语音模块的配置和烧录1.1 PIN引脚配置&#xff1a;1.2 设置唤醒词&#xff1a;1.3 设置控制详情&#xff1a;1.4 下载SDK并烧录到语音模块&#xff1a; 二、测试语音模块三、树莓派通过串…

汇舸环保从北交所转战港交所:狂分红超8000万,客户依赖度越来越高

《港湾商业观察》施子夫 7月31日&#xff0c;上海汇舸环保科技集团股份有限公司&#xff08;以下简称&#xff0c;汇舸环保&#xff09;递表港交所获受理&#xff0c;联席保荐机构中信证券和中国银河证券。 8月14日&#xff0c;公司披露公告称&#xff0c;另委任法国巴黎证券…

HTML零基础教程(超详细)

一、什么是HTML HTML&#xff0c;全称超文本标记语言&#xff08;HyperText Markup Language&#xff09;&#xff0c;是一种用于创建网页的标准标记语言。它通过一系列标签来定义网页的结构、内容和格式。HTML文档是由HTML元素构成的文本文件&#xff0c;这些元素包括标题、段…

99.WEB渗透测试-信息收集-网络空间搜索引擎shodan(1)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;98.WEB渗透测试-信息收集-Google语法&#xff08;12&#xff09; 信息收集方向-网络空间…

UEFI——获取UEFI MemoryMap

一、MemoryMap简介 首先讲一下什么是MemoryMap&#xff1f; 内存映射&#xff08;Memory Mapping&#xff09;是一种将文件内容映射到进程的虚拟地址空间的技术。在这种机制下&#xff0c;文件可以视为内存的一部分&#xff0c;从而允许程序直接对这部分内存进行读写操作&…