C到C++的升级
C和C++的关系
- C++继承了所有C语言的特性;
- C++在C的基础上提供了更多的语法和特性,C++语言去除了一些C语言的不好的特性。
- C++的设计目标是运行效率与开发效率的统一。
变化一:所有变量都可以在使用时定义
C++中更强调语言的实用性,所有的变量都可以在需要使用时定义。我们都知道C语言都必须要在作用域之前的位置定义,否则会报错。
引申概念,什么是作用域?
通常我们在写代码的时候,所用到的名字并不是有效/可用的,限定变量或者函数的名字的可用性的代码范围就叫作用域。全局变量作用域就是整个文件,加了extern声明之后作用域就可以为整个工程空间使用。局部变量的作用域就是本函数内,用完即丢弃。
范例:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{int c = 0;printf("Begin...\n");for(int i=0; i < 10; i++) //在C语言中,变量定义需要在函数开始,不能在使用的地方定义。{for(int j = 0; j < 10; j++){c += i*j;}}printf("c = %d\n", c);printf("End...\n");return 0;
}
C++编译器也可以编译C代码,通过Dev-C++软件分别创建C工程和C++工程,C++工程可以编译pass,C工程报错如下:
注意,使用ubuntu gcc编译能编译通过,因为Dev-C++ 的C编译器和GUN gcc 编译器遵循的标准不一样。GUN gcc 对标准C进行了扩展。
变化二:register关键字变化
- C语言中,register这个关键字请求编译器尽可能的将局部变量存在CPU寄存器中,而不是通过内存寻址访问,以提高效率。
注意是尽可能,不是绝对。因为,如果定义了很多register变量,可能会超过CPU的寄存器个数,超过容量。
C语言中无法取得register变量地址 - 在C++中依然支持register关键字。为了兼容C语言特性。
C++编译器有自己的优化方式,不使用register也可能做优化。
C++中可以取得register变量的地址,当C++编译器发现程序中需要取register变量的地址时,register对变量的声明变得无效。
早期C语言编译器不会对代码进行优化,因此register变量是一个很好的补充。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{register int c = 0;printf("Begin...\n");printf("&c = %08X\n", &c);printf("End...\n");return 0;
}
说明标准C不支持对register取地址。VC++6.0有警告,但是也可以获取寄存地址,只是说明编译器对register变量有处理,申请不掉register变量就变成普通变量。但是标准C是不支持的。
变化三:同名的全局变量处理
- 在C语言中,重复定义多个同名的全局变量是合法的,最终会被链接到全局数据区的同一个地址空间上。
- 在**C++**中,不允许定义多个同名的全局变量,C++拒绝这种二义性的做法。
#include <stdio.h>
#include <stdlib.h>
int c = 1;
int c;//加上extern 关键字,C++可以编译通过,表示在前面定义的。
int main(void)
{printf("Begin...\n");printf("&c = %08X\n", &c);printf("End...\n");return 0;
}
变化三 const 常量
- 在C中,const修饰的变量是不允许再次赋值的,但是可以通过指针操作const变量。const变量是只读变量,有自己的存储空间。
#include <stdio.h>
//const int c = 0;// const修饰全局变量,不可用指针操作修改值,会出现段错误。
int main(void)
{const int c = 0;int *p = (int*)&c;*p = 8;printf("c=%d\n", c);return 0;
}
- 在C++中,编译器对const常量处理:
- 当碰见const声明时,在符号表中放入常量;
- 编译过程中若发现使用常量,则直接以符号表中的值替换;
- 编译过程中若发现对const使用了extern或者&操作符,则给对应的常量分配存储空间。
Notice:C++编译器虽然可能为const常量分配空间,但不会使用其存储空间中的值。
如果再到上面的代码中插入打印C常量地址操作
printf("c address = %08X\n", &c);
最终打印如下:
c=0
c address = EB6F729C
- C中const变量是只读变量,告诉编译器该变量不能出现在赋值符号左边,本质是变量,有自己的存储空间。
- C++中const 是真正的常量,当const常量为全局,并且有extern关键字,或者使用&操作符取const常量地址时,才会分配地址空间。
为什么C++还要为const 常量分配地址空间呢?因为为了兼容C。
范例,加强const常量c和c++的理解:
#include <stdio.h>
int main(int argc, char *argv[])
{const int a = 1;const int b = 2;int array[a + b]={0};int i = 0;for (i = 0; i < (a+b); i++){printf("array[%d] = %d\n", i, array[i]);}return 0;
}
分别用gcc 和 g++编译运行结果:
C编译器直接报错,无法确定数组array的大小,因为const在c中本质是变量,编译器无法知道数组array的大小,变量只有在运行时候才知道值。
C++编译器作为常量处理,直接到符号表中取值,所以array[a+b] 就是array[1+2].
C++中的const小结
- const常量类似于宏定义,const int c = 0; ≈ #defin c 5
- c++中的const常量与宏定义不同
const 常量是由编译器处理的,提供类型检查和作用域检查。而宏定义由预处理器处理,简单的文本替换。
范例:
#include <stdio.h>
void f()
{#define a 3 //本意是想在本函数中使用a,作用域是该函数const int b = 4;//该变量作用域为f函数
}void g()
{printf("a = %d\n", a);//但是预编译器会直接替换掉a.printf("b =d %d\n", b);//编译会报错,因为编译器会对作用域进行检查
}int main(int argc, char *argv[])
{f();g();return 0;
}
变化四:struct类型的变化
- C语言的struct定义了一组变量的集合,C编译器并不认为这是一种新的类型。
- C++中的struct是一个新类型的定义声明。
#include <stdio.h>
struct Student
{const char* name;int age;
};int main(int argc, char *argv[])
{Student s1 = {"Tom", 30};Student s2 = {"Tony", 28};return 0;
}
C编译器认为Student 不是一个类型,所以报错。C++认为是一种新的类型,可以直接赋值。
- C++中所有的变量和函数都必须要有类型。
- C语言中的默认类型在C++中是不合法的。
范例:
#include <stdio.h>
f(i) //C语言默认类型 int f(int i)
{printf("i = %d\n", i);
}
g() //c语言默认类型 int g()
{return 5;
}int main(int argc, char *argv[])
{f(10);printf("g() = %d\n", g());//printf("g() = %d\n", g(1, 2, 3)); //在C中,这里打开也能编译通过。反之在C++中fail。return 0;
}
在C语言中,f(i) 和g()函数默认为 int f(int i) 和 int g();
g() 函数在C中可以接受任意的参数,所以在调用的地方写g(1,2,3)也能通过,只不过对传入的参数不处理。
如果C语言中想要表示不接受任何参数,则需要在函数括号中加void。
思考,int f();与int f(void); 的区别是什么?
- C语言中,int f();表示函数可以接受任意的参数,而 int f(void);表示调用时不接受任何参数否则就报错。
- C++中,int f();和int f(void) 都相同,表示函数不接受任何参数。对类型检测加强。
总结
- C++ 以C语言为基础,进行了加强。
- C++更强调实用性,可以在使用的时候声明变量,不需要在函数开头。
- C++中register只是向C兼容,C++编译器能够进行更好的变量优化。
- C++中的const是一个真正意义的常量,而不是只读变量。
- C++更加强调类型,任何函数和变量都必须要指明类型。
相关文章:

C到C++的升级
C和C的关系 C继承了所有C语言的特性;C在C的基础上提供了更多的语法和特性,C语言去除了一些C语言的不好的特性。C的设计目标是运行效率与开发效率的统一。 变化一:所有变量都可以在使用时定义 C中更强调语言的实用性,所有的变量…...

《热题101》动态规划篇
思路:需要一个二维数组dp来记录当前的公共子序列长度,如果当前的两个值等,则dp[i][j]dp[i-1][j-1]1,否则dp[i][j] max(dp[i-1][j],dp[i][j-1])。也就是说,当前的dp值是由左、上、左上的值决定的。获得dp数组之后,倒序…...

【综述+3D】基于NeRF的三维视觉2023年度进展报告(截止2023.06.10)
论文:2003.Representing Scenes as Neural Radiance Fields for View Synthesis 官方网站:https://www.matthewtancik.com/nerf 突破性后续改进: Instant Neural Graphics Primitives with a Multiresolution Hash Encoding | 展示官网&#…...

基于JavaScript粒子流动效果
这是一个HTML文件,主要包含了一些CSS样式和JavaScript代码,用于创建一个动画效果。 在CSS部分,定义了一些基本的样式,包括页面的背景颜色、位置、大小等。特别的,定义了两种球形元素(.ball_A 和 .ball_B&am…...

【U盘】实现U盘清空并重置恢复存储
打开电脑,将U盘插入USB端口,点按快捷键【WinR】,弹出运行对话框,输入命令 diskpart 进入命令提示符窗口 输入指令 list disk 查看现在的硬盘 这里显示的U盘编号是“1”,因此输入select disk “1”,就是选择…...

基于Hugo 搭建个人博客网站
目录 1.环境搭建 2.生成博客 3.设置主题 4.将博客部署到github上 1.环境搭建 1)安装Homebrew brew是一个在 macOS 操作系统上用于管理软件包的包管理器。类似于centos下的yum或者ubuntu下的apt,它允许用户通过命令行安装、更新和管理各种软件工具、…...

Springboot + Sqlite实战(离线部署成功)
最近有个需求,是手机软件离线使用, 用的springboot mybatis-plus mysql,无法实现,于是考虑使用内嵌式轻量级的数据库SQLlite 引入依赖 <dependency><groupId>org.xerial</groupId><artifactId>sqlite-…...

【后量子密码】CRYSTALS-KYBER 算法(一):MLWE 问题与NTT(附源码分析)
一、前言 大多数基于数论的密码学,如Diffie-Hellman协议和RSA加密系统,依赖于大整数因子分解或特定群的离散对数等困难问题。然而,Shor 在1997年给出了对所有这些问题的高效量子算法,这将使得基于数论的密码系统在未来量子计算机时代变得不安全。相比之下,目前对于格密码…...

VTK——angleWidget的3D转换
文章目录 3D空间坐标转换例程心得 3D空间坐标转换 在冠状图、矢状面、横截面等创建的角度组件的三个端点坐标,不能直接用在3D视图中。这是因为2D切片的坐标是基于像素的,而3D空间的坐标可能是基于实际物理尺寸的。 解决方案是使用2D点的坐标、切片的物理…...

HDFS 集群动态节点管理
目录 一、动态扩容、节点上线 1.1 背景 1.2 扩容步骤 1.2.1 新机器基础环境准备 1.2.2 Hadoop 配置 1.2.3 手动启动 DataNode 进程 1.2.4 Web 页面查看情况 1.2.5 DataNode 负载均衡服务 二、动态缩容、节点下线 2.1 背景 2.2 缩容步骤 2.2.1 添加退役节点 …...

postman9.12.汉化版(附有下载链接)
想用英文版本的可以直接点击下载最新版本 这里直接付上9.12.2版本的下载链接,如果大家要下载别的版本,可以直接修改链接里面的版本号即可 ,下面是汉化包下载 链接:https://pan.baidu.com/s/1izK3HfqlfXJdq6KIYeJ2zw?pwdpetk 提…...

mysql与msql2数据驱动
mysql基本使用 数据库操作(DDL) -- 数据考操作 -- 1.查询所有数据库 SHOW DATABASES;-- 2.选择数据库 USE learn_mysql;-- 3.当前正在使用的数据库 SELECT DATABASE();-- 4.创建数据库 CREATE DATABASE IF NOT EXISTS learn_mysql;-- 5.删除数据库 DRO…...

解决微信小程序回调地狱问题
一、背景 小程序开发经常遇到根据网络请求结果,然后继续 处理下一步业务操作,代码如下: //1第一个请求 wx.request({url:"https://example.com/api/",data:data,success:function(res){//2第二个请求 wx.request({url:"http…...

cron介绍
cron表达式在线生成 在使用定时调度任务的时候,我们最常用的,就是cron表达式了。通过cron表达式来指定任务在某个时间点或者周期性的执行。 cron表达式的组成 cron表达式是一个字符串,由6到7个字段组成,用空格分隔。其中前6个字…...

mkp勒索病毒的介绍和防范,勒索病毒解密,数据恢复
mkp勒索病毒是一种新兴的电脑病毒,它会对感染的电脑进行加密,并要求用户支付一定的赎金才能解锁。这种病毒已经引起了全球范围内的关注,因为它不仅具有高危害性,而且还有很强的传播能力。本文将对mkp勒索病毒进行详细介绍…...

【面试精品】关于面试会遇到的Apache相关的面试题
1. Apache HTTP Server 基于什么协议提供网页浏览服务? 答:基于标准的http网络协议提供网页浏览服务。 2. 简述编译安装httpd软件包的基本过程? 答:解包,配置,编译,安装。 3. 编译安装httpd软…...

python对文件转md5,用于文件重复过滤
直接上代码 import hashlibdef calculate_md5(file_path):# 创建 MD5 哈希对象md5_hash hashlib.md5()# 打开文件并逐块读取,更新哈希值with open(file_path, rb) as file:while True:data file.read(8192) # 逐块读取文件,每块大小为 8192 字节if n…...

mac苹果电脑删除顽固残留软件图标
核心:删除“启动台”数据库里对应app的信息 1、打开访达(Finder),点击最顶部菜单栏的【前往》前往文件夹】,接着输入【/private/var/folders】 2、在弹出的访达(Finder)窗口搜索栏输入【com.ap…...

【jsvue】联合gtp仿写一个简单的vue框架,以此深度学习JavaScript
用 gtp 学习 Vue 生命周期的原理 lifecycle.js function Vue(options) {// 将选项保存到实例的 $options 属性中this.$options options;// 若存在 beforeCreate 钩子函数,则调用之if (typeof options.beforeCreate function) {options.beforeCreate.call(this);…...

linux centos7 系统之编程:求水仙花数
在Python编程中,有列表、元组和字典三类变量可以使用,方便数据的存储与处理,而bash中仅有字符串变量、数组、函数可用,方法运用上受到限制,这与bash基于C语言,注重语法结构的严谨有关。而Python等高级语言更…...

git中的cherry-pick和merge有些区别以及cherry-pick怎么用
git中的cherry-pick和merge在使用场景上有些区别: cherry-pick用于将另一个分支的某一次或几次commit应用到当前分支。它可以选择性地拉取代码修改。merge用于将两个分支合并成一个新分支。它会把整个分支上的所有修改都合并过来。 具体区别:cherry-pick通常用于将bug修复从发…...

【前端】CSS-Flex弹性盒模型布局
目录 一、前言二、Flex布局是什么1、任何一个容器都可以指定为Flex布局2、行内元素也可以使用Flex布局3、Webkit内核的浏览器,必须加上-webkit前缀 三、基本概念四、flex常用的两种属性1、容器属性2、项目属性 五、容器属性1、flex-direction①、定义②、语句1&…...

Android AAPT: error: resource color 异常原因处理
异常体现: Android resource linking failed ERROR:E:\software\Developer\APP\GaoDeTest2\app\src\main\res\values\themes.xml:3:5-9:13: AAPT: error: resource color/purple_500 (aka com.example.gaodetest2:color/purple_500) not found.ERROR:E:\software\De…...

C++std::function和std::bind()的概念
std::function: 一个通用的函数封装器,它允许你存储和调用任何可以被调用的东西,例如函数、函数指针、函数对象、Lambda 表达式等。 std::bind: 用于创建函数对象。一个可调用对象的绑定版本,可以提前绑定某些参数&am…...

QT Creator工具介绍及使用
一、QT的基本概念 QT主要用于图形化界面的开发, QT是基于C编写的一套界面相关的类库,如进程线程库,网络编程的库,数据库操作的库,文件操作的库等。 如何使用这个类库:类库实例化对象(构造函数) --> 学习…...

python爬虫13:pymysql库
python爬虫13:pymysql库 前言 python实现网络爬虫非常简单,只需要掌握一定的基础知识和一定的库使用技巧即可。本系列目标旨在梳理相关知识点,方便以后复习。 申明 本系列所涉及的代码仅用于个人研究与讨论,并不会对网站产生…...

权限管理 ACL、RBAC、ABAC的学习
ACL(Access Control List:访问控制列表) 最简单的一种方式,将权限直接与用户或用户组相关联,管理员直接给用户授予某些权限即可。 这种模型适用于小型和简单系统,权限一块较为简单,并且角色和权限的变化较少。 RBAC(R…...

python的re正则表达式
一、正在表达式的方法(): re是Python中用于处理正则表达式的内置库,提供了许多有用的方法。以下是其中几个常用的方法: re.match(pattern, string): 尝试从字符串的开头匹配一个模式,如果匹配成功则返回匹…...

【算法与数据结构】700、LeetCode二叉搜索树中的搜索
文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析:二叉搜索树的性质:左节点键值 < 中间节点键值 < 右节点键值。那么我们根据此性质&am…...

SpringBoot v2.7.x+ 整合Swagger3入坑记?
目录 一、依赖 二、集成Swagger Java Config 三、配置完毕 四、解决方案 彩蛋 想尝鲜,坑也多,一起入个坑~ 一、依赖 SpringBoot版本:2.7.14 Swagger版本:3.0.0 <dependency><groupId>com.github.xiaoymin<…...