【c++复习】C++的基础知识(常用关键字、缺省参数、函数重载、引用)
C++基础
- 写在开头
- C++基础
- 常用关键字
- using namespace
- 流插入和流提取操作符
- 内联函数(inline)
- 宏
- auto关键字 (c++11
- nullptr (c++11
- 缺省参数
- 函数重载
- 引用
写在开头
C++基础部分我想介绍如下几个关键点:
- 常见关键字
- 命名空间的定义和使用
- 缺省参数
- 函数重载
- 引用、指针和引用的区别
- 内联函数
- 宏 ** C与C++结合
- 空指针NULL与nullptr的区别
可以看到C++的基础部分,需要掌握的知识多为零碎细小的知识,更需要总结和整理。
C++基础
常用关键字
C语言中有32个关键字,而在C++98中,总共给出了63个关键字。所有的关键字如下所示:
asm | do | if | return | try | continue |
---|---|---|---|---|---|
auto | double | inline | short | typedef | for |
bool | dynamic_cast | int | signed | typeid | public |
break | else | long | sizeof | typename | throw |
case | enum | mutable | static | union | wchar_t |
catch | explicit | namespace | static_cast | unsigned | default |
char | export | new | struct | using | friend |
class | extern | operator | switch | virtual | register |
const | false | private | template | void | true |
const_cast | float | protected | this | volatile | while |
delete | goto | reinterpret_cast |
我们在此总结一些比较常用的关键字。
using namespace
命名空间使用的目的是对标识符的名称进行本地化,避免命名冲突或命名污染
定义命名空间
namespace MySpace
{...
};
注意:
- 命名空间可以嵌套。
- 同一个工程可以存在多个相同名称的命名空间,编译器最终会合并成同一个。
- 定义一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该作用域。
使用命名空间
使用命名空间有三种方法。
-
加命名空间名称及作用域限定符
// namespace:MySpaceint main() {printf("%d", MySpace::a); }
-
使用using引入命名空间,或者引入命名空间中的某个成员
using MySpace::a; //引入某个成员 using MySpace; //引入整个命名空间
流插入和流提取操作符
- 流插入操作符:<<,流提取操作符:>>
- std是C++标准库的命名空间名,如果使用标准库中的函数或者其他定义,就需要使用命名空间std。
- 使用cout标准输出对象和cin标准输入对象,需要包含头文件,并且要按照命名空间使用方法使用std。
- cout、cin是全局的流对象,endl是特殊的c++符号,表示换行输出,都包含在中。
- 使用C++的输入输出很方便,不需要手动控制格式,而是由操作符自动识别变量类型。
- 流插入和流提取运算符在面对自定义类型时候,都涉及运算符重载。
内联函数(inline)
内联函数是以inline 修饰的函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数可以提升程序运行的效率。
特性:
- inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替换函数调用。缺点是可能会让目标文件变大,优点是少了函数调用的开销,提高了程序的运行效率。
- inline对于编译器而言只是建议,就像register 一样,不同编译器对inline实现机制可能不同。一般来说,将函数规模小(代码段短)、不是递归,且会频繁调用的函数采用inline修饰,否则会忽略inline建议。
- inline不建议声明和定义分离,分离会导致连接错误,因为inline被展开,就没有函数地址,链接找不到。
宏
宏的优点:增强代码的复用性、提高性能;
宏的缺点:不方便调试(在预编译阶段进行了替换)、代码可读性差、可维护性差、容易误用,没有类型安全的检查。
C++可以替换宏的技术:
- 常量定义: 换用const 或者 enum
- 短小函数定义改用inline。
auto关键字 (c++11
随着程序的复杂程度提高,类型名也越来越复杂,所以类型将会越来越难于拼写、含义不明确导致容易出错。
早期的auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量,但无人使用。
c++11中,auto有了全新定义:auto作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译的时期推导得到。
auto使用:
-
auto与指针和引用结合起来使用。
用auto声明指针类型时,用auto和auto* 没有任何区别,但用auto声明引用类型时必须加&
-
可在同一行定义多个变量
但是在同一行声明多个变量时,变量必须是相同类型,否则编译器会报错,因为编译器实际上只对第一个变量的类型进行推导,并用推导出来的类型定义其他变量。
-
auto 也有不能使用的场景:
- auto不能作为函数的参数
- auto不能直接用来声明函数
- auto旧的含义被舍弃了。
-
auto最常见的用法就是和范围for或者lambda结合。
nullptr (c++11
指针空值:nullptr。
声明一个变量时最好给变量一个合适的初始值。我们在定义指针时,如果它没有合法的指向,我们一般会定义其为:
int* p = NULL; //c
NULL实际上是一个宏,定义如下:
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void*)0)
#endif
#endif
可以看到,NULL可能被定义为字面常量0,或者被定义为无类型指针的常量。但是这些都会遇到麻烦:
void func(int)
{ cout << "func(int)" << endl; }
void func(int*)
{ cout << "func(int*)" << endl; }int main()
{func(0);func(NULL);func((int*)NULL);return 0;
}
程序的本意是用func(NULL) 调用指针版本的func(int*) 函数,但是因为NULL 被定义成0,所以调用了func(int) 版本。
在C++98中,字面常量0既可以是整型数字,也可以是无类型指针void*常量,但是编译器默认情况下看0作为一个整型常量,所以如果要将其按照指针方式使用的话, 必须强转(void🌟)0.
这无异给我们的使用带来了困扰,所以c++11中添加了nullptr。
- nullptr表示指针空值,不用包含头文件,因为其是作为C++11新关键字引入的。
- C++11中,sizeof(nullptr) 与 sizeof((void*)0)占用的字节数相同。
- 后续表示指针空值,一律用nullptr。
缺省参数
缺省参数是定义或者声明函数时为函数的参数指定一个缺省值。如果在调用函数时,没有给出对应的实参,就采用该形参的缺省值,否则使用指定的实参。
void func(int a = 10)
{cout << a << endl;
}
int main()
{func(1); //传了,用自己传的func(); //没传,用缺省的return 0;
}
缺省函数分类:
-
全缺省函数
函数的所有参数都有缺省值,意味着在调用函数的时候,可以不给任何实参。上面的func就是一个例子。
-
半缺省函数
void func(int a, int b = 10, int c = 20){cout << "a = " << a << endl;... }
上述就是半缺省函数,代表着在调用函数的时候,可以不给出部分参数的值。有注意事项:
- 半缺省参数必须从右往左依次给出,不能间隔。
- 缺省参数不能在函数的声明和定义中同时出现。
- 缺省值必须是常量或者全局变量。
- C语言不支持缺省函数。
函数重载
函数重载是函数的一种特殊情况,C++允许在同一个作用域下声明功能类似的同名函数,同名函数的形参列表(包括参数个数或者类型或者类型顺序)不同,常常用做处理实现功能类似数据类似的不同问题。接下来我们分开举例。
-
参数类型不同
//打算实现int类型和double类型的Add函数 int Add(int a, int b) {return a + b; } double Add(double a, double b) {return a + b; }
上述两个函数,参数的类型不同,但是函数名相同,这就构成了函数重载。
-
参数个数不同
void f() { cout << "void f()" << endl;} void f(int a) { cout << "void f(int a)" << endl; }
这就是参数个数不同而函数名相同构成的重载,如果我们调用f时不给任何参数,就会调用上面的无参版本;如果调用f时任给一个int 值,就会调用下面的带int 版本。
-
参数类型顺序不同
void f(char ch, int a) {cout << "void f(char ch, int a)" << endl; } void f(int a, char ch) {cout << "void f(int a, char ch)" << endl; }
参数的类型顺序如果稍有不同,也可以构成重载。
C不支持函数重载,而C++支持,其原因就是:C++支持函数重载的原理是 名字修饰 (name mangling)
C/C++中程序的运行需要经过几个步骤:预处理、编译、汇编、链接。
举个例子,现在有a.cc 、b.cc两个文件,在 b.cc中定义了Add函数,而在 a.cc中使用了Add函数。
编译后链接之前,a.o 的目标文件中没有Add的函数地址,因为Add是在b.cc中定义的,所以Add的地址在b.o 中。
在链接时,链接器看到a.o 调用Add,但是没有Add的地址,就会到b.o 的符号表中找Add的地址,然后链接到一起。
链接时,面对Add函数,链接器会使用一个名字去找。每个编译器的函数名修饰规则不同,gcc的函数名修饰过后不变(意味着不能同时出现两个同名函数),g++函数名修饰过后,变成了 _z + 函数长度 + 函数名 + 类型首字母,编译器将函数参数类型信息都添加到修改后的名字中。
正因如此:C语言无法支持函数重载,因为同名函数无法区分;而C++时通过函数修饰规则来区分,只要参数不同(参数类型,参数个数,参数类型顺序),修饰出来的名字就不同,所以支持重载。
如果两个函数的函数名和参数相同,而返回值不同,不构成重载,因为调用时编译器无法区分二者。编译器区分规则是:_z + 函数长度 + 函数名 + 类型首字母。
引用
引用不是新定义一个变量,而是给已经存在的变量取别名。变量和它的引用共用同一块内存空间。
引用特性:
-
引用在定义时必须初始化。
-
一个变量可以有多个引用。
-
引用一旦有了实体,就不能引用其他实体。
-
常引用: const 类型的对象,需要用常引用,即const + 类型+ & + 别名 = 实体。
const int a = 10; int & ra = a; //编译时报错,因为a 是常量,如果不加const,可能会修改。 const int& ra = a; //正确写法float b = 3.14; double& rb = b; //错误,类型变了。 const double& rb = b; //可以,表示别名rb不能修改b的值。
使用场景:
-
做参数
void Swap(int& a, int& b) {int temp = a;a = b;b = temp; }
只有当a 和b 是引用时,才奏效,就跟我们当时C语言传指针一样。
-
做返回值
int& Count() {static int n = 0;n++;return n; }
这里的n 是static静态的,所以可以用传引用返回,因为出了函数的作用域,n还存在。如果我们定义一个普通的对象,如下:
int& count() {int n = 0;n ++;return n; }
可以发现,出了函数的作用域,返回的对象已经销毁了,这时候必须使用传值返回。
传值和传引用的区别:
传值传参或者传值返回,函数不会直接传递参数或者将变量直接返回,而是传递这个参数或者返回值的临时拷贝,因此这样效率非常低,尤其是当参数或者返回值类型大的时候,效率更低。
引用和指针的区别:
- 语法概念上:引用就是别名,没有独立空间,和引用实体共用一块空间。
- 底层实现上:实际上是由空间的,因为引用是按照指针方式实现的。
- 引用概念上定义一个变量的别名,而指针存储一个变量的地址。
- 引用在定义时必须初始化,指针没有要求。
- 引用在初始化引用一个实体之后,不能引用其他实体;指针可以在任意时刻指向同类型实体。
- 没有NULL引用,但是有NULL指针。
- 在sizeof中含义不同,sizeof引用结果是引用类型的大小,指针始终是地址空间所占的字节。
- 引用++是引用实体++,指针++是指针向后偏移一个类型的大小。
- 有多级指针,没多级引用。
- 访问实体的方式不同,指针需要自己显式解引用,引用则是编译器自己处理。
- 引用比指针使用相对更安全。
以上就是C++入门时需要知道的基础知识。
相关文章:
【c++复习】C++的基础知识(常用关键字、缺省参数、函数重载、引用)
C基础写在开头C基础常用关键字using namespace流插入和流提取操作符内联函数(inline)宏auto关键字 (c11nullptr (c11缺省参数函数重载引用写在开头 C基础部分我想介绍如下几个关键点: 常见关键字命名空间的定义和使用缺省参数函数重载引用、指针和引用的区别内联函…...
Docker入门建议收藏 第二部分
二、Docker 容器技术与虚拟机的区别 Docker 到底是个什么东西呢?我们在理解 Docker 之前,首先得先区分清楚两个概念,容器和虚拟机。 虚拟机 虚拟机(Virtual Machine)指通过软件模拟的具有完整硬件系统功能的、运行在…...
蓝桥杯三月刷题 第7天
文章目录💥前言😉解题报告💥三角回文数🤔一、思路:😎二、代码:💥数数🤔一、思路:😎二、代码:💥数组切分🤔一、思路:😎二、…...
面试官问百万数据excel导出功能如何实现?
文章目录 背景实现1.异步处理1.1 使用job1.2 使用mq2.使用easyexcel4.多个sheet5.计算limit的起始位置6.文件上传到OSS7.通过WebSocket推送通知8.总条数可配置9.order by商品编号总结背景 用户在UI界面上点击全部导出按钮,就能导出所有商品数据。 咋一看,这个需求挺简单的。…...
理解HTTPS及配置
HTTP的弊端及HTTPS的由来 众所周知HTTP协议是以TCP协议为基石诞生的一个用于传输Web内容的一个网络协议,在“网络分层模型”中属于“应用层协议”的一种.那么在这里我们并不研究该协议标准本身,而是从安全角度去探究使用该协议传输数据本身存在的安全问题:(1)、通信使用明文(不…...
IP-guard浏览器上传下载智能加解密,让管理更省心省力
现在员工日常工作中经常会通过浏览器访问公司的业务系统(OA、JIRA等),或者访问其他外部系统,访问下载服务器的文档变得更便捷,工作地点也不再局限于办公室中。为确保应用系统机密安全且又不影响员工的正常工作…...
leetcode day22 位运算
位运算咋这么老难 剑指 Offer 56 - I. 数组中数字出现的次数 借评论区大佬答案:nums [1,2,10,4,1,4,3,3] a^a0a^0aa^b^ca^c^ba&(-a)最低位为1的二进制(从又到左)所有的异或结果得到sum2^108flag-8&88可分为两组,一组为与…...
java中如何判断map是否为空
java中判断map是否为空的方法是:利用isEmpty()函数来判断。函数介绍:isEmpty()是Java中用于判断某种容器是否有元素的系统库函数。如用来判断ArrayList,HashSet,HashMap是否有元素等。在Java中,可以用isEmpty();判断一…...
C语言数据结构:链表的增删改查及动态创建
目录 一,链表与数组 ① 定义区别 ② 实现区别 二,链表遍历和计算链表中节点数量 ① 链表遍历 ② 计算节点数量 三,查找链表节点 四,增加节点到链表中 ① 在节点后方插入 ② 在节点前方插入 ● 在头节点前方插入 ● 在…...
「Python 基础」I/O 编程、正则表达式
文章目录1. I/O 编程文件读写StringIO 和 BytesIO操作文件和目录序列化2. 正则表达式进阶re 模块1. I/O 编程 I/O指Input/Output; Input Stream 从外面(磁盘、网络)流进内存; Output Stream 从内存流到外面; 同步 …...
java 把pdf图片文档和文章文档转成文字的方法
java 提供了一些库和工具可以用来把 PDF 文档和图片文档转成文本。 Apache PDFBox:这是一个开源的 PDF 库,可以用来提取 PDF 文件中的文本内容。 iText:这是一个用于创建和处理 PDF 文件的库,可以用来提取 PDF 文件中的文本内容。…...
JavaScript 中的全部对象
宿主对象(host Objects):由 JavaScript 宿主环境提供的对象,它们的行为完全由宿主环境决定。 【 浏览器环境宿主,全局对象window,window 上又有很多属性,如 document。 全局对象 window 上的属…...
【教学典型案例】23.部分服务总是频繁出现掉线情况
目录一:背景介绍问题描述解决二:问题分析过程解决过程设计到的知识1、nacos的data目录作用。2、nacos data目下的protocol目录3、nacos ip混乱问题三:总结一:背景介绍 问题描述 因为某些特殊原因需要把nacos迁移到另一个版本的n…...
线程安全 List 效率测试
List 常见类以及各自优缺点可自行参考 https://blog.csdn.net/weixin_39883065/article/details/111197724 本机环境 java 版本:1.8.0_161 window 信息: 测试代码 下面通过代码测试 List 线程安全类 Vector、Collections.synchronizedList(List lis…...
LeetCode 热题 C++ 581. 最短无序连续子数组 617. 合并二叉树
581. 最短无序连续子数组 给你一个整数数组 nums ,你需要找出一个 连续子数组 ,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。 请你找出符合题意的 最短 子数组,并输出它的长度。 示例 1: 输入&am…...
鉴源论坛 · 观模丨模型检查综述
作者 | 李建文 华东师范大学软件工程学院博导 版块 | 鉴源论坛 观模 01 模型检查的历史 模型检查是一种起源于20世纪70年代末的形式化验证技术。该技术最初由Edmund M. Clarke、E. Allen Emerson和Joseph Sifakis提出,他们因在模型检查领域的贡献而获得了2007年的…...
Easy Deep Learning——池化层
池化是什么?它有什么作用? 还是草地的场景,把草地分成一块块的网格,数量还是太多了,如何继续简化输入数据呢? 这时候可以只取一块网格中所有的小草的大小形状的平均值或者最大值作为一个输入数据,这样就大…...
TryHackMe-VulnNet: Active(ez 域渗透)
VulnNet: Active VulnNet Entertainment在他们以前的网络中遇到了不好的时光,该网络遭受了多次破坏。现在,他们移动了整个基础架构,并再次聘请您作为核心渗透测试人员。您的目标是获得对系统的完全访问权限并破坏域。 这应该是我在thm打的最…...
TencentOS Server 安装 PostgreSQL
TencentOS 简介 2019 年,随着腾讯公司外部客户的需求,以及公司开源协同战略的推进,tlinux 对外开源并进行了品牌升级,升级为 TencentOS Server。TencentOS 包含三大场景,分别如下: TencentOS Server&…...
多线程的风险 --- 线程安全
✨个人主页:bit me👇 ✨当前专栏:Java EE初阶👇 ✨每日一语:低头赶路,敬事如仪;自知自心,其路则明。 目 录🍸一. 线程不安全🍹二. 线程不安全的原因…...
Linux信号详解
文章目录Linux信号什么是信号**从生活角度理解: **技术应用角度的信号进程的注意事项信号概念用kill -l命令可以察看系统定义的信号列表信号处理常见方式概览信号产生通过终端按键产生信号使用signal函数自定义SIGINT信号的处理方式使用sigprocmask函数阻塞2号信号和40号信号vo…...
JAVA使用POI操作EXCEL
设置公式totalRow.createCell(4).setCellFormula("SUM(E9:E35");// 执行公式wb.setForceFormulaRecalculation(true);合并单元格sheet.addMergedRegion(new CellRangeAddress(0, 0, 3, 7));单元格格式CellStyle cellStyle wb.createCellStyle();// 字体XSSFFont fon…...
只做笔记有必要买apple pencil吗?苹果笔的代替笔推荐
如果仅仅使用IPAD来进行打游戏和看剧的话,未免有些浪费。ipad的作用还是挺大的,可以用来做学习笔记,也可以用来做绘画,也可以用来做一些重要的内容。很多人都会认为,苹果的电容笔很好用,但是价格上要比一般…...
Hive---sqoop安装教程及sqoop操作
sqoop安装教程及sqoop操作 文章目录sqoop安装教程及sqoop操作上传安装包解压并更名添加jar包修改配置文件添加sqoop环境变量启动sqoop操作查看指定mysql服务器数据库中的表在hive中创建一个teacher表跟mysql的mysql50库中的teacher结构相同将mysql中mysql50库中的sc数据导出到h…...
【C++】register 关键字
文章目录一. 什么是寄存器?二. 为什么要存在寄存器?三. register 修饰变量一. 什么是寄存器? 我们都知道,CPU主要是负责进行计算的硬件单,但是为了方便运算,一般第一步需要先把数据从内存读取到CPU内&…...
剑指 Offer II 024. 反转链表
题目链接 剑指 Offer II 024. 反转链表 easy 题目描述 给定单链表的头节点 head,请反转链表,并返回反转后的链表的头节点。 示例 1: 输入:head [1,2,3,4,5] 输出:[5,4,3,2,1] 示例 2: 输入:h…...
从Linux内核中学习高级C语言宏技巧
Linux内核可谓是集C语言大成者,从中我们可以学到非常多的技巧,本文来学习一下宏技巧,文章有点长,但耐心看完后C语言level直接飙升。 本文出自:大叔的嵌入式小站,一个简单的嵌入式/单片机学习、交流小站 从…...
详解Python的装饰器
Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里。 为什么需要装饰器 我们假设你的程序实现了say_hello()和say_goodbye()两个函数。 def say_hello():print "hello!"def say_goodbye():print "hello!" # bug hereif…...
k8s-Pod域名学习总结
k8s-Pod域名学习总结 大纲 k8s内置DNS服务 配置Pod的域名服务 CornDNS配置 默认Pod的域名 自定义Pod的域名 实战需求 1 Pod有自己的域名 2 集群内部的Pod可以通过域名访问其他的Pod 基础准备: 1 k8s 集群版本1.17 k8s内置DNS服务 k8s1.17安装完成后自动创建…...
0405习题总结-不定积分
文章目录1 不定积分的基本概念2 直接积分法-基本积分公式3 第一换元法-凑微分形式法4 第二类换元法5 分部积分求不定积分6 表格法积分7 有理函数求积分后记1 不定积分的基本概念 例1 f(x){x1,x≥012e−x12,x<0求∫f(x)dxf(x) \begin{cases} x1,\quad x\ge0\\ \frac{1}{2}e^…...
wordpress4.1/三只松鼠营销案例分析
前提准备在打开 Xcode 之前,我们需要准备两个库:GLFW 和 GLAD。这是开发 OpenGL 需要依赖的库,所以先看看如何准备好这两个库吧:GLFW在我们画出任何效果之前,首先要做的就是创建一个OpenGL上下文和一个用于显示的窗口。…...
公司官方网站怎么做/网络推广代运营公司
import numpy as np temp np.array([[0.8, 0.2]]) print(temp.shape) action np.random.choice(2, ptemp.ravel())# ravel从一维度降到二维度。 print(action)# 0,1;0.8,0.2(以这两个概率选择0和1)语法介绍ÿ…...
个人网站可以做论坛/网站推广seo
有很多的Java程序员,在初期学习时,通常会对如何学习而感到迷茫。本文千锋工作Java小编就为大家分析如何学好Java编程,相信能帮助那些正在处于迷茫状态的初学者。 1、培养兴趣 兴趣是能够让你坚持下去的动力,如果只是把写程序作为…...
亚马逊一般在哪些网站上做推广/网络营销师资格证
思科交换机与H3C交换机端口聚合配置 一、网络环境 本网络是广东粤电大厦,3台交换机做端口聚合的课题 网络环境:H3C_A交换机<----------------->H3C_B交换机<----- ----------------------->cisco(3560)交换机 H3C_B交换机做为中心交换机 由于…...
关于加强政府网站信息内容建设的实施意见/营销型网站建设推荐
修改表所属表空间:alter table 表名 move tablespace "表空间名称" 修改表索引所属表空间:alter index 索引名 rebuild tablespace "表空间名称" 查询某表空间的所有表:select segment_name from dba_segments where own…...
网站里的聊天怎么做的/做网络优化哪家公司比较好
ns(nanosecond):纳秒, 时间单位。一秒的10亿分之一,即等于10的负9次方秒。常用作 内存读写速度的单位,其前面数字越小则表示速度越快。1纳秒1000 皮秒1纳秒 0.001 微秒1纳秒0.000001 毫秒1纳秒0.00000 0001秒java的System.curren…...