【C++】C++入门的杂碎知识点

思维导图大纲:

 namespac命名空间

  •  什么是namespace命名空间
  • namespace命名空间有什么用

什么是命名空间 

namespace命名空间是一种域,它可以将内部的成员隔绝起来。举个例子,我们都知道有全局变量和局部变量,全局变量存在于全局域中,局部变量存在于局部域中,看下段代码 ,根据已经学习的知识我们都知道局部优先,所以输出会打印局部变量的数据。

#include <stdio.h>

// 全局域
int a = 10;

int main()
{
	// 局部域
	int a = 0;
	printf("%d", a);
}

由上述代码可以知道,不同的域可以存在相同名称的变量,而输出函数会优先在最近的域中寻找变量a,如果找不到才去全局找。那么有没有一种办法可以绕过局部域,打印全局域的变量a呢,答案是声明我们要打印的变量来源。 

#include <stdio.h>

// 全局域
int a = 10;

int main()
{
	// 局部域
	int a = 0;
	printf("%d\n", a);
	// 在变量名称前加上:: 这样编译器就知道到全局域中寻找了
	printf("%d\n", ::a);
}

通过以上我们大概了解了域方面的知识,那么什么是namespac命名空间呢,简单的说就是一个我们可以自定义的域,在这个域中我们可以存放函数/变量等等,同时因为具有域的特性,我们在多人合作项目时,可以各种取一个命名空间,这样我们可以使用相同命名的函数或者变量了 。

namespace关键字,后面的ouyang1可以任意取名: 

#include <stdio.h>

// 命名空间
namespace ouyang1
{
	int a = 15;
}

namespace ouyang2
{
	int a = 20;
}

int main()
{
	printf("%d\n", ouyang1::a);
	printf("%d\n", ouyang2::a);
}

当然在你需要使用什么内部成员时声明一下就可以了 ,以下时使用不同成员声明的代码表述。

namespace ouyang
{
	// 变量
	int a = 10;
	// 函数
	int add(int x, int y)
	{
		return x + y;
	}
	// 结构体
	struct student_name
	{
		char name[20];
	};
	// 枚举
	enum
	{
		red = 1,
		blue,
		yellow
	};

}

int main()
{
	printf("%d\n", ouyang::a);
	printf("%d\n", ouyang::add(1, 3));
	struct ouyang::student_name s1;
	printf("%d\n", ouyang::red);
	printf("%d\n", ouyang::blue);
	printf("%d\n", ouyang::yellow);

}

 命名空间的作用:

命名空间可以防止命名冲突的发生,同时每一个命名空间都相当于一个域,访问需要声明获得权限,简单说就相当于我们所划定的领域,这样的设计可以使我们在团队项目中避免冲突发生。

命名空间的展开: 

那么我们每次去使用命名空间时,都需要在前声明会不会有点麻烦,为了解决这一问题,c++语法中还包含了命名空间的展开,展开代码如下:

// 命名空间
namespace ouyang
{
	int a = 10;
}
// 命名空间的展开
using namespace ouyang;

展开命名空间,就相当于对编译器开放了该命名空间的访问权限,但是注意域的访问顺序还是存在先后的,首先编译器还是会到局部域中去寻找,其次才是全局域和命名空间域。 

这种展开有好也有坏,好处是:我们可以随意访问命名空间内的成员,坏的一方面如果命名空间展开的成员过多,不可避免会产生命名冲突问题,如以下代码:

// 命名空间
namespace ouyang
{
	int a = 10;
}
// 命名空间的展开
using namespace ouyang;

int a = 0;

int main()
{
	printf("%d", a);
	return 0;
}

 由于展开命名空间后,编译器访问全局域和命名空间域的优先程度一致,所以编译器无法区分究竟因该访问哪一个。

命名空间的局部展开: 

为了防止展开太多出现以上情况,c++语法中又提出了局部展开,就是展开到特定的成员,这样可以大大降低了命名冲突带来的报错,也方便快速查找问题。 

局部展开代码展示: 

// 命名空间
namespace ouyang
{
	int a = 10;
	int b = 5;
}
// 命名空间的局部展开
using ouyang::b;

int main()
{
	printf("%d", b);
	return 0;
}

 有了局部展开后,我们以后想访问命名空间的谁再去展开,这样既可以优化代码的冗长度,又可以很好的控制使用。

C++的输入输出

  • cout
  • cin
  • endl

前提:我们都知道c语言中使用输入输出函数scanf/printf需要包括头文件#include<stdio.h>,同样c++语法中使用以上的函数也需要包含头文件#include <iostream>。 

cout输出符 

上一个知识点我们了解了命名空间,c++在使用头文件时,为了避免命名冲突,也给其中的成员创建了命名空间域用于保护,如我们要使用的输入输出等等的函数都包含着命名空间std中。 

注意:c++是在c语言的基础上衍生的,所以可以适用c语言的语法 

代码使用方式: 

#include <stdio.h>
#include <iostream>
using namespace std;

int main()
{
	// 变量
	int a = 10;
	double b = 13.14;
	char c = 'a';
	// c语言的输入输出
	printf("C语言:");
	printf("%d %lf %c\n", a, b, c);
	// c++语言的输入输出
	// << 这个符号叫做流插入 / << 还有另外的一层意思就是左位移操作符
	// cout会自动识别类型输出
	cout << "C++:   ";
	cout << a << " " << b << " " << c << '\n';
}

 cin输入符

 cin输入符可以制动识别输入的数据类型存放到相应的变量之中。

代码演示: 

int main()
{
	// 变量
	int a = 0;
	double b = 0;
	char c = 0;
	// 流提取
	cin >> a >> b >> c;
	cout << a << " " << b << " " << c <<endl;
}

注:endl符相当于换行 

 函数重载:

定义:在同一个域中,可以存在相同命名的函数,但是这些函数需要满足以下条件之一:

  • 1.参数的类型不同
  • 2.参数的个数不同
  • 3.参数的顺序不同

 代码演示:

// 函数重载

// 全局域中,交换函数Swap
void Swap(int* a, int* b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}

void Swap(double* a, double* b)
{
	double tmp = *a;
	*a = *b;
	*b = tmp;
}
int main()
{
	int num1 = 1, num2 = 2;
	double num3 = 1.1, num4 = 2.2;
	cout << "交换前:" << endl;
	cout << num1 << " " << num2 << " " << num3 << " " << num4 << endl;

	// 交换
	Swap(&num1, &num2);
	Swap(&num3, &num4);

	cout << "交换后:" << endl;
	cout << num1 << " " << num2 << " " << num3 << " " << num4 << endl;
	return 0;
}

 以上是函数重载中的参数类型不同,以下还有参数数量不同,参数顺序不同:

// 参数数量不同

void print(int a, double b, char c)
{
	cout << "print(int a, double b, char c)" << endl;
}

void print(int a, double b)
{
	cout << "print(int a, double b)" << endl;
}

int main()
{
	print(1, 1.1, 'a');
	print(1, 1.1);
	return 0;
}

// 函数重载
// 参数顺序不同
void swap(int* a, double* b)
{
	cout << "swap(int* a, double* b)" << endl;
}

void swap(double* a, int* b)
{
	cout << "swap(double* a, int* b)" << endl;
}
int main()
{
	int num1 = 1;
	double num2 = 1.1;
	swap(&num1, &num2);
	swap(&num2, &num1);
	return 0;
}

引用 

引用符号->& 

引用的定义:引用相当于给变量取一个别名,就像张三,我们平日可能会叫他老张,张三,也可能会叫小张,但这些所有的称呼都指向一个人张三,引用的作用就是这样: 

// 引用
int main()
{
	int a = 0;
	int& b = a;
	b++;
	cout << "a=" << a << " " << "b=" << b << endl;
	return 0;
}

以上代码我们可以看见,我们给变量a取了一个别名b,我们在使用b++的时候就相当于a++,所有最后的结果a=1。

 权限放大和权限缩小问题

我们在给变量取别名的时候,可以通过别名对变量进行修改,但如果我们的变量由const修饰之后怎么办呢,这就涉及到权限放大和权限缩小问题

1. 权限可以缩小,不可以放大

int main()
{
	// 权限放大不被允许
	const int a = 10;
	// int& b = a; // err

	// 权限缩小允许
	int a = 10;
	const int& b = a;
}

2. 拥有常量属性的变量权限不可以放大。

如以下代码:

int main()
{
	int x = 1, y = 2;

	// int& c = x + y; // x+y这种临时变量具有常性 // err
	const int& c = x + y;
	return 0;
}

应用场景 

  • 做参数
  • 做返回值 

做参数可以在交换函数中替代指针的适用。

void Swap(int& a, int& b)
{
	int tmp = a;
	a = b;
	b = tmp;
}

int main()
{
	int a = 1, b = 2;
	cout << a << " " << b << endl;
	Swap(a, b);
	cout << a << " " << b << endl;
}

 做返回值可以用于接收结果。

int& Add(int a, int b)
{
	int c = a + b;
	return c;
}
int main()
{
	int ret = Add(1, 2);
	Add(3, 4);
	cout << "Add(1, 2) is :" << ret << endl;
	return 0;
}

引用和指针的区别 

  • 1. 引用在语法上不开空间,底层和指针一样需要开空间,但是我们应用层面默认为不开空间
  • 2. 引用必须初始化,而指针可以不用,或者指向空
  • 3.引用在初始化一个实体后,不能在改成别的实体,但是指针可以改变指向
  • 4.引用自加是实体加1,而指针加1,是指向的类型位置+1
  • 5.有多级指针,没有多级引用
  • 6.指针的大小由sizeof计算是固定的,区别是64位机器还是32位机器,但是引用的大小与引用的实体相关,比如说:引用的类型int,大小4字节;引用的类型double,大小8字节
  • 7.引用比指针安全
  • 8.访问方式上,指针需要解引用,但是引用不需要,编译器会自己处理 

缺省参数 

我们往往有时候在使用函数时会忘记传入参数,那么有没有一种办法在我们没有传参的情况下,函数可以使用默认的值进行传入使用呢?这就是缺省参数

// 全缺省
// 传值按传值来,不传值按默认来
void print1(int a = 1, int b = 1, int c = 1)
{
	cout << a << " " << b << " " << c << endl;
}

// 半缺省 -> 没有缺省的参数必须传值
void print2(int a, int b = 1, int c = 1)
{
	cout << a << " " << b << " " << c << endl;
}

int main()
{
	print1();
	print1(10);
	print1(10, 20);
	print1(10, 20, 30);

	print2(10);
	print1(10, 20);
	print1(10, 20, 30);
	return 0;
}

注意: 缺省只能从右往左缺省,缺省参数不可以跳跃传参!

不允许)跳跃传参的演示如下: 

// 传值按传值来,不传值按默认来
void print1(int a = 1, int b = 1, int c = 1)
{
	cout << a << " " << b << " " << c << endl;
}



int main()
{
	print1(, 10, );// err
	return 0;
}

 内联函数

定义:和c语言中的宏类似,被修饰的函数不会去使用地址调用,只会在原地展开,这种内联函数只适用于代码量少,简单的函数,并且原地展开的请求只是对编译器的建议,如果函数过大,编译器可以默认不执行展开改为调用,同时由于是原地展开,内联函数无法声明与定义分离,会在链接时报错找不到函数的地址。 

// 内联函数
inline int add(int x, int y)
{
	return x + y;
}

int main()
{
	int ret = add(1, 2);
	cout << ret << endl;
	return 0;
}

auto关键字 

定义:自动识别变量类型

使用方式如下:

// auto 关键字
int main()
{
	auto a = 10;
	auto b = 13.14;
	auto c = 'a';
	cout << a << " " << b << " " << c << endl;
	return 0;
}

 

打印类型的函数typeid(变量名).name() 

int main()
{
	int x = 10;
	auto a = &x;
	auto* b = &x;
	auto& c = x;
	cout << typeid(a).name() << endl;
	cout << typeid(b).name() << endl;
	cout << typeid(c).name() << endl;
	*a = 20;
	*b = 30;
	c = 40;
	return 0;
}

 范围for

代码展示如下:

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9 };
	for (auto x : arr)
	{
		cout << x << " ";
	}
	// 如果要改变arr中的值,使用&
	for (auto& x : arr)
	{
		x *= 2;
	}
	cout << endl;
	for (auto x : arr)
	{
		cout << x << " ";
	}
}

 空指针nullptr

在c语言中我们已经了解了空指针NULL,但是在c++语法中实现时,却存在一个坑,c++语法中的NULL 定义为0 ,而不是(void*)0 ,就会导致以下代码情况。

void pint(int)
{
	cout << "void pint(int)" << endl;
}

void pint(int*)
{
	cout << "void pint(int*)" << endl;
}

int main()
{
	int i = 0;
	pint(i);
	pint(NULL);
	pint(nullptr);
}

 注意:

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

 

 

 

 

 

 

 

 

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

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

相关文章

趣味C语言——【猜数字】小游戏

&#x1f970;欢迎关注 轻松拿捏C语言系列&#xff0c;来和 小哇 一起进步&#xff01;✊ &#x1f389;创作不易&#xff0c;请多多支持&#x1f389; &#x1f308;感谢大家的阅读、点赞、收藏和关注&#x1f495; &#x1f339;如有问题&#xff0c;欢迎指正 感谢 目录 代码…

抖音混剪素材哪里找?可以混剪搬运视频素材网站分享

在抖音上制作精彩的视频离不开高质量的素材资源。今天&#xff0c;我将为大家推荐几个优质的网站&#xff0c;帮助你解决素材短缺的问题。这些网站不仅提供丰富的素材&#xff0c;还符合百度SEO优化的规则&#xff0c;让你的视频更容易被发现。 蛙学府素材网 首先要推荐的是蛙…

模拟自动滚动并展开所有评论列表以及回复内容(如:抖音、b站等平台)

由于各大视频平台的回复内容排序不都是按照时间顺序&#xff0c;而且想看最新的评论回复讨论内容还需逐个点击展开&#xff0c;真的很蛋疼&#xff0c;尤其是热评很多的情况&#xff0c;还需要多次点击展开&#xff0c;太麻烦&#xff01; 于是写了一个自动化展开所有评论回复…

诊断解决方案——CANdesc和MICROSAR

文章目录 一、CANdesc二、MICROSAR一、CANdesc canbeded是Vector汽车电子开发软件Nun Autosar标准的工具链之一。 canbeded是以源代码的形式提供的可重用的组件,包括CAN Driver,交互层(IL),网络管理(NM),传输层(TP),诊断层(CANdesc) , 通信测量和标定协议(CCP,XCP) 和 通信控…

Es 索引查询排序分析

文章目录 概要一、Es数据存储1.1、_source1.2、stored fields 二、Doc values2.1、FieldCache2.2、DocValues 三、Fielddata四、Index sorting五、小结六、参考 概要 倒排索引 优势在于快速的查找到包含特定关键词的所有文档&#xff0c;但是排序&#xff0c;过滤、聚合等操作…

并发容器(二):Concurrent类下的ConcurrentHashMap源码级解析

并发容器-ConcurrentHashMap 前言数据结构JDK1.7版本HashEntrySegment 初始化 重要方法Put方法扩容rehash方法 前言 之前我们在集合篇里聊完了HashMap和HashTable&#xff0c;我们又学习了并发编程的基本内容&#xff0c;现在我们来聊一聊Concurrent类下的重要容器&#xff0c…

tsp可视化python

随机生成点的坐标并依据点集生成距离矩阵&#xff0c;通过点的坐标实现可视化 c代码看我的这篇文章tsp动态规划递归解法c from typing import List, Tuple import matplotlib.pyplot as plt from random import randintN: int 4 MAX: int 0x7f7f7f7fdistances: List[List[in…

最长不下降子序列LIS详解

最长不下降子序列指的是在一个数字序列中&#xff0c;找到一个最长的子序列&#xff08;可以不连续&#xff09;&#xff0c;使得这个子序列是不下降&#xff08;非递减&#xff09;的。 假如&#xff0c;现有序列A[1&#xff0c;2&#xff0c;3&#xff0c;-1&#xff0c;-2&…

60.WEB渗透测试-信息收集- 端口、目录扫描、源码泄露(8)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;59.WEB渗透测试-信息收集- 端口、目录扫描、源码泄露&#xff08;7&#xff09; 御剑是用…

植物大战僵尸杂交版全新版v2.1解决全屏问题

文章目录 &#x1f68b;一、植物大战僵尸杂交版❤️1. 游戏介绍&#x1f4a5;2. 如何下载《植物大战僵尸杂交版》 &#x1f680;二、解决最新2.1版的全屏问题&#x1f308;三、画质增强以及减少闪退 &#x1f68b;一、植物大战僵尸杂交版 《植物大战僵尸杂交版》是一款在原版《…

【Android】三种常见的布局LinearLayout、GridLayout、RelativeLayout

【Android】三种常见的布局LinearLayout、GridLayout、RelativeLayout 在 Android 开发中&#xff0c;布局&#xff08;Layout&#xff09;是构建用户界面的基础。通过合理的布局管理&#xff0c;可以确保应用在不同设备和屏幕尺寸上都能有良好的用户体验。本文将简单介绍 And…

困惑度作为nlp指标的理解示例

为了更清晰地说明困惑度的计算过程以及如何通过困惑度判断模型的优劣&#xff0c;我们可以通过一个简单的例子来演示。假设我们有一个非常简单的文本语料库和两个基础的语言模型进行比较。 示例文本 假设我们的文本数据包括以下两个句子&#xff1a; “cat sits on the mat”…

蔡崇信“预言”:微软与OpenAI未来极有可能会分道扬镳

近日&#xff0c;在美国投行摩根大通于上海举行的第二十届全球中国峰会上&#xff0c;阿里巴巴集团联合创始人、董事局主席蔡崇信与摩根大通北亚区董事长兼大中华区投资银行业务副主席关金星&#xff08;Kam Shing Kwang&#xff09;进行了一场精彩对话。蔡崇信深入分享了他对公…

线上教育培训办公系统系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;教师管理&#xff0c;学生管理&#xff0c;运营事件管理 教师账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;学生管理&#xff0c;作业管理&#xff0c;电…

OpenCore 引导完美升级

备份原有 OC (做好回滚的准备下载新版 OpenCore https://github.com/acidanthera/OpenCorePkg/releases将 1, 3, 4 里面的文件使用新版进行替换 4 里面的文件严格来说并不需要, 只是留着方便使用不追求完美到这就可以收工了将 OC 复制到 U 盘 EFI U 盘格式化可以使用: diskutil…

js 用正则表达式 匹配自定义字符之间的字符串数据,如:( )、[ ]、{ }、< >、【】等括号之间的字符串数据

要使用正则表达式匹配尖括号()之间的数据&#xff0c;可以使用以下代码示例&#xff1a; 在JavaScript中&#xff0c;你可以使用正则表达式来匹配括号()之间的数据。以下是一个简单的例子&#xff0c;它展示了如何使用正则表达式来获取两对括号之间的文本。 // 示例字符串 con…

Spring-kafka消费者消费的一些问题

前言 Spring Kafka 无缝集成了 Spring Boot、Spring Framework 及其生态系统中的其他项目&#xff0c;如 Spring Cloud。通过与 Spring Boot 的自动配置结合&#xff0c;开发者可以快速启动和配置 Kafka 相关的功能。无需编写大量样板代码即可实现 Kafka 的生产和消费功能&…

现在用U盘的人还多吗?多用于哪些场景?

在公司中使用U盘的人仍然相当多&#xff0c;主要在以下场景下使用&#xff1a; 数据存储与备份&#xff1a;U盘作为一种便携式存储设备&#xff0c;被广泛应用于数据的存储和备份。对于需要经常在不同设备或地点之间传输数据的员工来说&#xff0c;U盘提供了一个方便、快捷的解…

如何使用ios自带语音转文字工具?

ios自带语音转文字是iOS系统中自带的语音转文字功能主要应用于以下几个方面&#xff1a; 1. 语音输入&#xff1a;在iOS的任何文本输入框中&#xff0c;通常都有一个麦克风图标&#xff0c;点击后可以进行语音输入&#xff0c;系统会将你的语音实时转换成文字。 2. Siri&…

ESD与EOS区别

最近小白在做项目时&#xff0c;被一个实习生问道了&#xff0c;关于EOS与ESD区别。说实话&#xff0c;以前专注于测试debug的我&#xff0c;在回答对方时&#xff0c;并没法做到太全面的解答。于是乎&#xff0c;借助周内的空闲时间&#xff0c;小白还是简单学习总结了一番。 …