【01】C++入门

文章目录

  • Ⅰ 命名空间
    • 1. 命名空间域的产生
    • 2. 命名空间域的定义
    • 3. 命名空间域的使用
  • Ⅱ 缺省参数
    • 1. 缺省的概念
    • 2. 缺省的分类
    • 3. 声明和定义不能同时存在缺省参数
  • Ⅲ 函数重载
    • 1. 函数重载概念
    • 2. 编译器如何实现函数重载
  • Ⅳ 引用
    • 1. 引用的概念
    • 2. 引用的特性
    • 3. 引用的使用场景
    • 4. 引用和指针的区别
  • Ⅴ 内联函数
    • 1. 内联函数的概念
    • 2. 内联函数的特性

Ⅰ 命名空间

1. 命名空间域的产生

  • 在开发过程中,常用的名字也就那么多。在同一个域内,如果自己定义的变量和别人已定义好后的变量冲突了,此时就必须更改名字才行。
int a = 10;	// 张三在一个区域内定义的一个变量 a// 若干行代码后......int a = 5;	// 李四在同一个区域内定义的同名变量,此时两个人定义的变量就产生了冲突
  • 上述情况就被叫做命名冲突,而且如果你想更改自己的变量名就又不知道可能会和谁的同域变量名冲突,毕竟取过名的都知道好用的名字大概率给人取走了。
  • 此时就需要使用 namespace 关键字 来划分一块属于自己的命名空间域,在这块区域内就可以对标识符的名称进行本地化,以避免命名冲突或名字污染

2. 命名空间域的定义

1. 命名空间的定义语法

namespace 该命名空间的名字
{// 在这里可以自己定义命名空间的成员// 命名空间的成员包括 变量、函数、自定义类型
}

2. 命名空间的定义示例

namespace T1				// T1 是我自己取的这个空间域的名字
{int a = 10;				// 可以定义变量int b = 5;int Add(int x, int y)	// 可以定义函数{return x + y;}struct Node				// 可以自定义类型{int data;struct Node* next;};
}

3. 命名空间域的使用

如果想使用上面示例的命名空间域 T1 内的成员的话有三种方法:

1. 命名空间名 + 域作用限定符 + 命名空间内的成员

  • 域作用限定符 :: 使用 :: 这个域作用限定符能够指定到某个区域内寻找该变量。
int main()
{printf("%d\n", T1::a); // 指定使用 T1 这块区域内的 a 变量struct T1::Node head;
}
  • 注意:如果某个变量在全局和局部都有定义,一般来说会优先使用局部变量,也可以使用域作用限定符指定使用全局变量
int k = 10;				// 全局变量 kint main()
{int k = 5;			// 局部变量 kprintf("%d\n", k);	// 5 优先使用局部的变量printf("%d\n", ::k);// 10 域作用限定符左边什么都没有表示指定使用全局变量
}

2. 使用 using 将命名空间中的某个成员引入

  • 语法:using 空间域名::空间域的成员名,这样之后使用该成员都是到指定的命名空间域,但是其他的成员还是要用第一种方法才能使用。
using T1::a;	// 之后的代码 a 都是指定使用 T1 这块空间的int main()
{printf("%d %d\n",a, T1::b);
}

3. 使用 using namespace 命名空间名 引入

  • 还是优先使用局部区域的变量,如果该变量不在局部区域,则去命名空间域内搜索该变量。
  • 该方法能够让命名空间域内的成员像普通变量一样直接使用,不需要加上域作用限定符。
using namespace T1;	// 可直接使用 T1 这块空间内的成员int main()
{printf("%d %d\n",a ,b);printf("%d\n", Add(a, b));
}

Ⅱ 缺省参数

1. 缺省的概念

  • 缺省参数是声明或者定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参,则采用该形参的缺省值,否则使用指定的实参。

在这里插入图片描述

2. 缺省的分类

  • 缺省参数分为全缺省和半缺省两类。

1. 全缺省参数

  • 函数的所有形参都带有一个默认的缺省值。

在这里插入图片描述

2. 半缺省参数

  • 半缺省参数指的是部分缺省,而不是刚好就缺一半。
  • 半缺省参数只能从右往左依次给出,且不能间隔着给

在这里插入图片描述

在这里插入图片描述

3. 声明和定义不能同时存在缺省参数

  • 如果一个函数的声明和定义同时存在缺省参数,且声明和定义提供的缺省参数恰好值不同,此时编译器无法判断该使用谁的缺省值
  • 所以,缺省参数必须只放在声明

在这里插入图片描述

Ⅲ 函数重载

1. 函数重载概念

  • 同一作用域中声明几个功能类似的同名函数,这些函数的形参列表 (形参的个数、类型、类型顺序) 不同,用来对不同的数据类型实现相同的功能。
  • 函数重载与函数的返回值无关,只与函数的形参列表有关

1. 参数类型不同

在这里插入图片描述

2. 参数个数不同

在这里插入图片描述

3. 参数类型顺序不同

  • 本质还是类型不同

在这里插入图片描述

2. 编译器如何实现函数重载

  • 在 C 语言中,是利用函数名去找函数的地址,如果有同名函数,就没法区分。
  • 在 C++ 中,使用函数名修饰规则,在函数名中引入参数类型 (各个编译器自己实现)。
  • 现在主要讲解在 Linux 下的 g++ 编译器是如何实现在函数名中引入参数类型。

Linux 下 g++ 编译器的函数名修饰规则

  • _Z + 函数名长度+ 函数名 + 参数类型1 + 参数类型 2 + 参数类型 n
void Print(char a, int b);// 上述函数使用函数名修饰规则就可以变成 _Z + 5 + Print + c + i → _Z5Printci。
// 使用修饰后的函数名,编译器就可以找到使用者具体是要调用哪个函数
  • 如果形参是指针则将指针类型修饰成 p + 该指针指向的数据类型。
void Func(int* a);	// int* 就可以修饰成 pi,整个函数可以修饰成 _Z4Funcpi
void Func(char* b);	// char* 可以修饰成 pc,整个函数可以修饰成 _Z4Funcpc

Ⅳ 引用

1. 引用的概念

语法数据类型& 别名 = 原变量名

作用:给变量取别名,对这个别名进行得操作能够影响到原变量的内容。

示例

在这里插入图片描述

注意引用类型必须和引用实体是同种类型的

2. 引用的特性

1. 引用在定义时必须初始化

  • 也就是得有原名才能取别名。
int& ra;		// × 如果没有原名,那取别名还有什么意义

2. 一个变量可以有多个引用

  • 即一个变量可以取多个别名,这些别名指的都是该变量。
int a = 10;
int& ra = a;
int& rra = ra;	// ra 和 rra 都是 a 的别名,对这两个别名进行操作都会影响到原变量 a

3. 引用定义后,不能再改变指向

  • 鲁迅已经是周树人的别名了,它就不能再是其他任何人的别名。
int a = 10;
int b = 20;int& ra = a;	// √ 
ra = b;			// × ra 已经是 a 得别名,不能再做其他人得外号了

3. 引用的使用场景

1. 做函数的形参

  • 在 C 语言中,函数形参如果想要改变实参,那么只能使用址传递的方式。实参需要传地址,而形参需要用指针接收。

在这里插入图片描述

  • 在 C++ 中就不用那么麻烦了,将形参定义为引用类型,形参是实参的别名,能直接修改实参的值。

在这里插入图片描述

  • 而如果想要传一级指针变量的地址,那么在 C 语言中就需要使用二级指针来接收,引用就只需要使用对一级指针的引用即可。

在这里插入图片描述

2. 做函数的返回值

  • 局部变量不能用引用返回
int& func()
{int a = 10;	// a 是局部变量,出了该函数就会被销毁return a;	// 如果返回 a 的别名,就相当于野引用
}int main()
{int& ret = func(); // ret 是 a 的别名的别名,ret 成了野引用
}
  • 静态变量 / 全局变量 / 堆上变量 可以用引用返回。这几种类型的变量出了函数的作用域也不会被销毁。
// 返回静态变量的别名
int& func1()	
{static int a = 10;return a;
}// 返回全局变量的别名
int b = 20;
int& func2()	
{return b;
}// 返回堆上变量的别名
int& func3(int*& arr)
{// ...return arr[0];
}int main()
{func1();func2();int* arr = (int*)malloc(4 * sizeof(int));func3(arr);return 0;
}

4. 引用和指针的区别

1. 从语法的角度看

  1. 引用是别名,不用开空间指针是地址,需要开空间存地址
  2. 引用必须初始化,指针可以选择是否初始化,所以指针更容易出现野指针。
  3. 引用不能改变指向,指针可以。
  4. 没有空引用,引用更安全,不容易出现野引用。有空指针,容易出现野指针。
  5. 在 sizeof 中引用结果为引用类型的大小,指针始终为 4 / 8 字节。
  6. 有多级指针,但没有多级引用
  7. 访问实体方式不同,指针需要显式解引用,引用是编译器自己处理。

2. 从底层的角度看

  1. 从汇编层面上看,没有引用,都是指针。引用编译后也会转换成指针。

Ⅴ 内联函数

  • 在调用函数的时候是会开辟栈帧的,如果某一个函数非常频繁的被调用,那么栈空间的压力就会非常大。

在这里插入图片描述

  • 此时就出现了内联关键字 inline,将栈帧的压力转移。

1. 内联函数的概念

  • 在编译的时候,编译器会在调用内联函数的地方将内联函数的实现逻辑展开
  • 没有函数调用建立栈帧的开销,内联函数能够有效提升程序运行的效率。

在这里插入图片描述

2. 内联函数的特性

内联函数的优缺点

inline 内联函数是一种以空间换时间的方式,在编译阶段,会用函数体替换函数调用

  1. 缺点:可能会使编译好的可执行程序变大。假设一个内联函数有 50 行,有 1万 个调用该函数的地方,那么这个文件就会多出 50 万行文本的大小。
  2. 优点:不用每次调用都开辟栈帧,可以提高程序的运行效率。

何时使用内联函数

  • 函数体内容小于等于 75 行时可以选择使用内联函数。

不建议声明和定义分离

  • 如果函数声明有 inline 而函数定义没有,就可能导致链接错误。
  • 因为inline被展开,就没有函数地址了,链接就会找不到。

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

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

相关文章

云服务器也能挂游戏 安卓模拟器

安卓模拟器云服务器 什么是BlueStacks模拟器主机? 特网科技基于Windows操作系统预装了BlueStacks Android模拟器您能够通过Android模拟器安装Android应用程序、如APP游戏、安卓APP、APP游戏等。 我可以在主机上安装应用程序吗? 你可以在BlueStacks模…

css1基础选择器

大纲 一.标签选择器 比较简单,前面直接写目标标签 二.类选择器 应用 例子 三.多类名选择器(调用时中间用空格隔开) 四.id选择器 应用 五.通配符选择器 应用 六.总结

汽车租赁系统

目录 一.研究背景 二.系统架构 1、SSM 2、JAVA 3、MySQL 4、系统架构 三.系统功能 1、车辆管理 2、客户管理 3、销售管理 4、统计分析 四.系统实现 五.结论总结 一.研究背景 传统的销售与信息统计管理都主要依靠人工,处理出的销售数据量与使用管理系统…

SpringBoot第二天

Bean管理 Bean扫描 在Spring中&#xff0c;Bean的扫描有两种写法 第一种是在xml配置文件中用标签扫描 <context:component-scan basepackage"com.cacb"/> 第二种是是注解扫描 ComponentScan(basePackages"com.cacb") 而在SpringBoot中&#xf…

Stable Diffusion 模型下载:EnvyHyperrealXL01

模型介绍 一个基于 EnvyHyperdrive 和 NewReality 的超写实模型&#xff0c;使生成的照片级真实感模型在主题和视觉上与我的其他模型相似&#xff0c;除了&#xff0c;你知道&#xff0c;照片级真实感。 &#x1f603; 条目内容类型大模型基础模型SDXL 1.0来源CIVITAI作者_En…

《Python 网络爬虫简易速速上手小册》第5章:Python 数据存储与管理(2024 最新版)

文章目录 5.1 选择数据存储方案5.1.1 重点基础知识讲解5.1.2 重点案例&#xff1a;使用 SQLite 存储博客文章数据5.1.3 拓展案例 1&#xff1a;使用 MongoDB 存储社交媒体动态5.1.4 拓展案例 2&#xff1a;使用 Elasticsearch 存储和检索日志数据 5.2 数据清洗与预处理5.2.1 重…

【动态规划】【树形dp】【C++算法】968监控二叉树

作者推荐 【动态规划】【字符串】【表达式】2019. 解出数学表达式的学生分数 本文涉及知识点 动态规划汇总 LeetCode:968监控二叉树 给定一个二叉树&#xff0c;我们在树的节点上安装摄像头。 节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。 计算监控树的所…

springcloud-gateway升级版本allowedOrigins要改allowedOriginPatterns

前言 报错: java.lang.IllegalArgumentException: When allowCredentials is true,allowedOrigins cannot contain the special value "*"since that cannot be set on the "Access-Control-Allow-Origin"response header. To allow credentials to a se…

计算机网络_1.6.3 计算机网络体系结构分层思想举例

1.6.3 计算机网络体系结构分层思想举例 1、实例引入&#xff08;用户在主机中使用浏览器访问web服务器&#xff09;2、从五层原理体系结构的角度研究该实例3、练习题 笔记来源&#xff1a; B站 《深入浅出计算机网络》课程 本节通过一个常见的网络应用实例&#xff0c;来介绍计…

解决Android camera 录像中拍照帧率不足30fps

问题现象 camera录像中拍照&#xff0c;录出来的视频帧率为29.3fps&#xff0c;未达到30fps。 问题分析 这个场景相当于跑了previevediocapture&#xff0c;极其损耗性能。 当前场景CPU频率已处于最高。 抓取systrace分析。 1&#xff0c;分析掉帧直接原因 SinkNode存在大…

四、Redis之配置文件

redis配置文件的名称 redis.conf 通过命令 find / -name redis.confvim redis.conf通过 : set nu 设置行号: set nonu 取消行号/关键字 搜索关键字: set noh 取消高亮选择4.1 Units 配置大小单位&#xff0c;开头定义了一些基本的度量单位&#xff0c;只支持 bytes&#…

《Vue3 基础知识》 使用 GoGoCod 升级到Vue3+ElementPlus 适配处理

此篇为 《Vue2ElementUI 自动转 Vue3ElementPlus&#xff08;GoGoCode&#xff09;》 的扩展&#xff01; Vue3 适配 Vue3 不兼容适配 Vue 3 迁移指南 在此&#xff0c;本章只讲述项目或组件库中遇到的问题&#xff1b; Vue3 移除 o n &#xff0c; on&#xff0c; on&#…