C/C++语言基础--从C到C++的不同(下),15个部分说明C与C++的不同
本专栏目的
- 更新C/C++的基础语法,包括C++的一些新特性
前言
- 1-10在上篇C/C++语言基础–从C到C++的不同(上);
- 当然C和C++的不同还有很多,本人暂时只总结这些,其他的慢慢更新;
- 上一篇C/C++语言基础–从C到C++的不同(上)受到了不少人的喜欢,因此,本人抓紧赶出下篇,欢迎大家点赞 + 收藏 + 关注;
- C语言后面也会继续更新知识点,如内联汇编;
- 本人现在正在写一个C语言的图书管理系统,1000多行代码,包含之前所学的所有知识点,包括链表和顺序表等数据结构,请大家耐心等待!!
思维导图如下
文章目录
- 11. 枚举类型
- 1,C语言中的enum
- 2,C++中的enum
- 3,C++中的 enum class 强枚举类型
- 小结
- 12. auto自动类型推导
- 13. for循环遍历
- 14. 类型信息
- 15. 函数
- 内联函数
- 函数默认参数
- 占位参数
- 函数重载
- **函数重载的不同**
- **重载函数的调用匹配规则**
- 函数重载遇上默认参数
11. 枚举类型
C语言和C++语言都提供了枚举类型,两者是有一定区别。
有如下定义:
enum SHAPE {CIRCLE,RECT,LINE,POINT};
enum WEEK {MON,TUE,WED,THI,FIR,SAT,SUN};
1,C语言中的enum
-
允许非枚举值赋值给枚举类型,允许其他枚举类型的值赋值给另一个枚举类型
enum WEEK today = 3; //正确 today = CIRCLE; //正确
-
枚举具有外层作用域,容易造成名字冲突
(在不同作用域不会冲突,但是遵循就近原则,访问不到外层作用域的枚举)
enum OTHER { RECT };//error C2365: “RECT”: 重定义;以前的定义是“枚举数”
int RECT = 12; //同上
- 不同类型的枚举值可以直接比较
if (CIRCLE == MON)
{printf("oh.yes");
}
2,C++中的enum
- 只允许赋值枚举值
enum WEEK today = 3; //错误 error C2440: “初始化”: 无法从“int”转换为“main::WEEK”
today = CIRCLE; //错误 error C2440: “=”: 无法从“main::SHAPE”转换为“main::WEEK”
- 枚举元素会暴露在外部作用域,不同两个枚举类型,若含有相同枚举元素,则会冲突
enum OTHER { RECT }; //错误 error C2365: “RECT”: 重定义;以前的定义是“枚举数”
int RECT = 12; //错误同上 但是可以通过枚举名访问指定的枚举属性
OTHER::RECT; //正确
- 不同类型的枚举也可以直接比较
if (CIRCLE == MON)
{cout<<"oh.yes";
}
3,C++中的 enum class 强枚举类型
enum class SHAPE {CIRCLE,RECT,LINE,POINT};
enum class WEEK {MON,TUE,WED,THI,FIR,SAT,SUN};
- 强枚举类型不会将枚举元素暴露在外部作用域,必须通过枚举名去访问
cout<<SHAPCE::RECT<<endl; //输出 1
- 不相关的两个枚举类型不能直接比较,编译报错
if (SHAPE::CIRCLE == WEEK::MON) //error C2676: 二进制“==”:“main::SHAPE”不定义该运算符或到预定义运算符可接收的类型的转换
{cout<<"oh.yes";
}
小结
- C语言中,枚举可以暴露在外面,且可以枚举与非枚举之间进行比较,赋值等操作;
- C++中,枚举可以暴露外外面,但是不可以枚举与非枚举之间进行赋值,但是可以比较;
- C++强枚举中,不可以暴露在外面,必须指明作用域才能使用,枚举与非枚举之间不能进行比较,赋值,就算是枚举与枚举之间,不相关的枚举之间也不行。
12. auto自动类型推导
在 C++11 之前的版本中,定义变量或者声明变量之前都必须指明它的类型
,比如 int、char 等,这个其实很不方便,尤其是在复杂项目的时候,有多个命名空间,如:Boost::asio::ip::tcp
等等,而在其他语言,如js,就只需要用关键字var
或者let
定义变量就行,到C++11后,auto
诞生了,可以在编译的时候制动推导替换类型。
注意:auto 仅仅是一个占位符,在编译器期间它会被真正的类型所替代。或者说,C++ 中的变量必须是有明确类型的,只是这个类型是由编译器自己推导出来的。
- 使用 auto 类型推导的变量
必须
马上初始化 - auto
不能在函数的参数
中使用(但是
能作为函数的返回值) - auto 不能作用于类的
非静态成员变量
(也就是没有 static 关键字修饰的成员变量)中 - auto 关键字不能定义数组
- auto 不能作用于模板参数
13. for循环遍历
对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还会容易犯错误,因此C++大叔给我们提供了一个简单的方法,如下:
int arr[]={1,2,3,4,5,6,7};
//一般用法
for(int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
{cout<<arr[i]<<" ";
}
//新用法
for(int i:arr)
{cout<<i<<" ";
}
特点:
- 从数组的第一个元素开始,逐个赋值给迭代变量;
- 不依赖于下标元素,通用;
- 但是,经常还是喜欢用第一种,哈哈哈哈哈哈哈。
14. 类型信息
typeid 是一个运算符,用来获取一个表达式的类型信息。
typeid 的操作对象既可以是表达式,也可以是数据类型,下面是它的两种使用方法:
typeid( dataType )
typeid( expression )
typeid 会把获取到的类型信息保存到一个 type_info 类型的对象里面,并返回该对象的常引用;当需要具体的类型信息时,可以通过成员函数来提取,本质是一个类,封装了大量的API,如下:
//获取一个普通变量的类型信息
int n = 100;
const type_info& nInfo = typeid(n);
cout << nInfo.name() << " | " << nInfo.raw_name() << " | " << nInfo.hash_code() << endl;//获取一个字面量的类型信息
const type_info& dInfo = typeid(25.65);
cout << dInfo.name() << " | " << dInfo.raw_name() << " | " << dInfo.hash_code() << endl;//获取一个普通类型的类型信息
const type_info& charInfo = typeid(char);
cout << charInfo.name() << " | " << charInfo.raw_name() << " | " << charInfo.hash_code() << endl;//获取一个表达式的类型信息
const type_info& expInfo = typeid(20 * 45 / 4.5);
cout << expInfo.name() << " | " << expInfo.raw_name() << " | " << expInfo.hash_code() << endl;
其中:
- name() 用来返回类型的名称。
- raw_name() 用来返回名字编码(Name Mangling)算法产生的新名称。。
- hash_code() 用来返回当前类型对应的 hash 值。
除此之外,还可以用 == 比较两个类型是否相等,如下:
char *str;
int a = 2;
int b = 10;
float f;
类型判断结果为:
类型比较 | 结果 | 类型比较 | 结果 |
---|---|---|---|
typeid(int) == typeid(int) | true | typeid(int) == typeid(char) | false |
typeid(char*) == typeid(char) | false | typeid(str) == typeid(char*) | true |
typeid(a) == typeid(int) | true | typeid(b) == typeid(int) | true |
typeid(a) == typeid(a) | true | typeid(a) == typeid(b) | true |
typeid(a) == typeid(f) | false | typeid(a/b) == typeid(int) | true |
建议:内容很多,这个其实也并不常用,可以留个映像,到后面用到的时候查询即可。
15. 函数
内联函数
函数调用时,通过哈希表,需要跳转到函数的地址去执行,执行完成后返回到被调用函数,比较费时,因此,C++中提供了一种操作方式,允许编译时直接把函数替换到调用处,即内联函数。
// 使用:
inline int add(int a, int b) {return a + b;
}
为什么使用内联函数?
内联函数没有普通函数调用时的额外开销(压栈,跳转,返回)
注意:
- 内联函数声明时inline关键字必须和函数定义结合在一起,否则编译器会直接忽略内联请求。
- C++编译器不一定准许函数的内联请求!(只是对编译器的请求,因此编译器可以拒绝)
- 现代C++编译器能够进行编译优化,
因此一些函数即使没有inline声明,也可能被编译器内联编译
C++中内联函数的限制:- 不能存在任何形式的循环语句
- 不能存在过多的条件判断语句
- 函数体不能过于庞大
- 不能对函数进行取址操作
- 编译器对于内联函数的限制并不是绝对的,内联函数相对于普通函数的优势只是省去了函数调用时压栈,跳转和返回的开销。因此,当函数体的执行开销远大于压栈,跳转和返回所用的开销时,那么内联将无意义。
总结:上面内容过多,很难记住,我也记不住,我只记住了:内联函数可以直接跳转到函数地址中执行,省去入栈出栈等开销,还有就是内联函数之间不能写太多东西。
函数默认参数
定义函数时可以给形参指定一个默认的值,这样调用函数时如果没有给这个形参赋值(没有对应的实参),那么就使用这个默认的值。
void showX(int x = 666)
{cout<<"x:"<<x<<endl;
}
showX();
showX(6);
小结:
- 有函数声明时,默认参数可以放在声明或定义中,但不能同时存在
int add(int a,int b = 5);
int add(int a,int b)
{return a+b;
}
- 注意:函数声明时,必须按照从右向左的顺序,依次给与默认值。
int foo(int a, int b = 2, int c = 3); // 正确
int foo1(int a, int b = 2, int c); // 错误, i3未指定默认值
int foo2(int a = 1, int b, int c = 3); // 错误, i2未指定默认值
占位参数
定义函数时,还可以给函数提供占位参数
- 占位参数只有参数类型,而没有参数名
- 在函数体内部无法使用占位参数
- 占位参数也可以指定默认参数
void func(int a,int = 0)
{cout<<a<<endl;
}
func(2);
函数重载
不知道在C语言写函数的时候会不会遇到这种情况,想函数名难想(不想直接拼音),而如果想实现以下功能:
int add(int a, int b) {return a + b;
}int add(double a, double b) {return a + b;
}
想实现以上功能的时候,好像名字都可以用add
,故在C++的时候,引入了一个新的概念,函数重载。(当然上面的实现还可以更加简介,他可用模板,这个后面会更新)。
函数重载是指:在同一作用域
内,可以有一组具有相同函数名
,不同参数列表
的函数,这组函数被称为重载函数。
函数重载的不同
- 参数个数不同
- 参数类型不同
- 参数顺序不同
- 函数重载与返回值类型无关
来个例子体会一下,比较不同类型的两个变量的大小
int maxmum(int a, int b)
{return a > b?a:b;
}
long maxmum(long int a, long int b)
{return a > b ? a : b;
}
char maxmum(char a, char b)
{return a > b ? a : b;
}
double maxmum(double a, double b)
{return a > b ? a : b;
}
const char* maxmum(const char* str1,const char* str2)
{return strcmp(str1, str2)==1?str1:str2;
}
char* maxmum(char* str1, char* str2)
{return strcmp(str1, str2) == 1 ? str1 : str2;
}int main()
{cout << maxmum(2, 6) << endl;cout << maxmum(2L, 6L) << endl;cout << maxmum('A', 'C') << endl;cout << maxmum("maye", "MAYE") << endl;char str1[] = "hello";char str2[] = "hello";cout << maxmum(str1, str2) << endl;return 0;
}
函数重载可以根据具体的参数去决定调用哪一个函数。
重载函数的调用匹配规则
- 精确匹配:参数匹配而不做转换,或者只是做微不足道的转换,如数组名到指针、函数名到指向函数的指针;
- 提升匹配:即整数提升(如bool 到 int、char到int、short 到int),float到double
- 使用标准转换匹配:如int 到double、double到int、double到long double、Derived到Base、T到void、int到unsigned int;
函数重载遇上默认参数
如果在给重载函数的时候指定默认参数时,这个时候很容易造成函数冲突,如下:
void fun(int a)
{cout << "fun(int a) " << a << endl;
}
void fun(int a, int b = 8)
{cout << "fun(int,int =8) " << a <<" "<< b << endl;
}
int main()
{//fun(5); //error C2668: “fun”: 对重载函数的调用不明确fun(5, 6);//正确return 0;
}
相关文章:

C/C++语言基础--从C到C++的不同(下),15个部分说明C与C++的不同
本专栏目的 更新C/C的基础语法,包括C的一些新特性 前言 1-10在上篇C/C语言基础–从C到C的不同(上);当然C和C的不同还有很多,本人暂时只总结这些,其他的慢慢更新;上一篇C/C语言基础–从C到C的不同(上&…...

物理感知扩散的 3D 分子生成模型 - PIDiff 评测
PIDiff 是一个针对蛋白质口袋特异性的、物理感知扩散的 3D 分子生成模型,通过考虑蛋白质-配体结合的物理化学原理来生成分子,在原理上,生成的分子可以实现蛋白-小分子的自由能最小。 一、背景介绍 PIDiff 来源于延世大学计算机科学系的 Sang…...

蓝桥杯-基于STM32G432RBT6的LCD进阶(LCD界面切换以及高亮显示界面)
目录 一、页面切换内容详解 1.逻辑解释 2.代码详解 code.c(内含详细讲解) code.h main.c 3.效果图片展示 编辑 二、页面选项高亮内容详解 1.逻辑解释 2.读入数据 FIRST.第一种高亮类型 code.c(内含代码详解) code.…...

2022高教社杯全国大学生数学建模竞赛C题 问题一(1) Python代码
目录 问题 11.1 对这些玻璃文物的表面风化与其玻璃类型、纹饰和颜色的关系进行分析数据探索 -- 单个分类变量的绘图树形图条形图扇形图雷达图 Cramer’s V 相关分析统计检验列联表分析卡方检验Fisher检验 绘图堆积条形图分组条形图 分类模型Logistic回归随机森林 import matplo…...
【3D打印】3D打印机运动控制“Gcode”
一、Gcode是什么? Gcode是一种用于控制数控机床(包括3D打印机)的语言。它由一系列指令组成,每个指令控制机器的一个特定动作。 二、基础术语 G指令:用于控制机器的运动。M指令:用于控制机器的其他功能&a…...
针对Chsrc换源工具的简单脚本
此脚本目前只是针对 X86和aarch64系统,可根据自身需求进行修改,点赞自取 关于工具的详细介绍请看上一篇文章:全平台通用的换源工具Chsrc #!/bin/bashtag1"https://gitee.com/RubyMetric/chsrc/releases/download/pre/chsrc-x64-linux&…...

vscode中如何配置c/c++环境
“批判他人总是想的太简单 剖析自己总是想的太困难” 文章目录 前言文章有误敬请斧正 不胜感恩!一、准备工作二、安装 VSCode 插件三、配置 VSCode1. 配置编译任务(tasks.json)2. 配置调试器(launch.json) 四、运行和调…...
【梯度消失|梯度爆炸】Vanishing Gradient|Exploding Gradient——为什么我的卷积神经网络会不好呢?
【梯度消失|梯度爆炸】Vanishing Gradient|Exploding Gradient——为什么我的卷积神经网络会不好呢? 【梯度消失|梯度爆炸】Vanishing Gradient|Exploding Gradient——为什么我的卷积神经网络会不好呢? 文章目录 【梯度消失|梯度爆炸】Vanishing Gradi…...
MAC 地址简化概念(有线 MAC 地址、无线 MAC 地址、MAC 地址的随机化)
一、MAC 地址 MAC 地址(Media Access Control Address),即媒体访问控制地址,也称为物理地址、硬件地址或链路层地址 MAC 地址有时也被称为物理地址,但这并不意味着 MAC 地址属于网络体系结构中的物理层,它…...

SQL_yog安装和使用演示--mysql三层结构
目录 1.什么是SQL_yog 2.下载安装 3.页面介绍 3.1链接主机 3.2创建数据库 3.3建表操作 3.4向表里面填内容 3.5使用指令查看效果 4.连接mysql的指令 4.1前提条件 4.2链接指令 编辑 4.3创建时的说明 4.4查看是不是连接成功 5.mysql的三层结构 1.什么是SQL_yog 我…...
蓝桥杯-STM32G431RBT6(解决LCD与LED引脚冲突的问题)
一、LCD与LED为什么会引脚冲突 LCD与LED引脚共用。 网上文章是在LCD_WriteRAM、LCD_WriteRAM_Prepare、LCD_WriteReg中添加,但问题并没有解决。 二、使用步骤 在如下函数中加入uint16_t tempGPIOC->ODR; GPIOC->ODRtemp; LCD_Init(); void LCD_C…...
ESP-01S,ESP8266设置客户端透传模式
ESP-01S,ESP8266设置透传(透明传输)模式 例子 ATCWMODE_DEF1 //station模式 ATRST //重启 ATCWLAP //查看周围热点 ATCWJAP_DEF"ssid","password" //连接热点 ATCIFSR //查看ip ATCIPSTA_DEF"192.168.82.66","192.168.6.1&…...

NFT Insider #147:Sandbox 人物化身九月奖励上线;Catizen 付费用户突破百万
市场数据 加密艺术及收藏品新闻 Doodles 动画特别剧《Dullsville and The Doodleverse》在多伦多国际电影节首映 Doodles 最近在多伦多国际电影节(TIFF)首映了其动画特别剧《Dullsville and The Doodleverse》,这是该品牌的一个重要里程碑。…...

103.WEB渗透测试-信息收集-FOFA语法(3)
免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 内容参考于: 易锦网校会员专享课 上一个内容:102.WEB渗透测试-信息收集-FOFA语法(2) FOFA使用实例 组件框架 …...

SpringDataJPA基础增删改查
添加:save(对象) 删除:delete(主键或者带有主键的对象) 修改:save(对象) 对象中没有id,执行添加操作 对象中有id id不存在:执行添加 id存在: 其余数据…...

好代码网同款wordpress主题,完全开源无加密可二开
这个其实就是好代码网站的早期整站打包代码,当时售价198的,现在里面的部分数据已经过期了,只能展示效果,没法下载。所以就只当做主题分享给大家使用。 资源下载类网站目前还是红利期,搞个特价主机和域名,再…...
如何在@GenericGenerator中显式指定schema
现在的情况是,在MySQL中有db1和db2两个数据库。项目使用Hibernate,可同时访问db1和db2,默认数据库为db1。表table2在db2中。且table2的主键名为ids,是自增长字段(Auto Increment)。 table2和ids的定义为&a…...

感知器神经网络
1、原理 感知器是一种前馈人工神经网络,是人工神经网络中的一种典型结构。感知器具有分层结构,信息从输入层进入网络,逐层向前传递至输出层。根据感知器神经元变换函数、隐层数以及权值调整规则的不同,可以形成具有各种功能特点的…...

【C++】——继承详解
目录 1、继承的概念与意义 2、继承的使用 2.1继承的定义及语法 2.2基类与派生类间的转换 2.3继承中的作用域 2.4派生类的默认成员函数 <1>构造函数 <2>拷贝构造函数 <3>赋值重载函数 <4析构函数 <5>总结 3、继承与友元 4、继承与静态变…...
RocketMQ 消费方式
在消息传递系统中,“推(Push)”和“拉(Pull)”是两种不同的消息消费方式,RocketMQ 也支持这两种模式。下面是对这两种模式的详细解释: 1. 推模式(Push Model) 模式简介…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...

【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...

Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...

并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...