C语言与C++的区别终于有人说清楚了!

点击蓝字

5bd3e9c6093932beeaa314274cdd49de.png

关注我们

来源于网络,侵删

1、前言

在很大程度上,C++是C的超集,这意味着一个有效的C程序也是一个有效的C++程序。

C和C++的主要区别是,C++支持许多附加特性。但是,C++中有许多规则与C稍有不同。这些不同使得C程序作为C++程序编译时可能以不同的方式运行或根本不能运行。

本节着重讨论这些区别。如果使用C++的编译器编译C程序,就知道这些不同之处。虽然C和C++的区别对本书的示例影响很小,但如果把C代码作为C++程序编译的话,会导致产生错误的消息。

C99标准的发布使得问题更加复杂,因为有些情况下使得C更接近C++。

例如,C99标准允许在代码中的任意处进行声明,而且可以识别//注释指示符。在其他方面,C99使其与C++的差异变大。

例如,新增了变长数组和关键字restrict。C11缩小了与C++的差异。

例如,引进了char16_t类型,新增了关键字_Alignas,新增了alignas宏与C++的关键字匹配。C11仍处于起步阶段,许多编译器开发商甚至都没有完全支持C99。

我们要了解C90、C99、C11之间的区别,还要了解C++11与这些标准之间的区别,以及每个标准与C标准之间的区别。这部分主要讨论C99、C11和C++之间的区别。当然,C++也正在发展,因此,C和C++的异同也在不断变化。

2、函数原型

在C++中,函数原型必不可少,但是在C中是可选的。这一区别在声明一个函数时让函数名后面的圆括号为空,就可以看出来。在C中,空圆括号说明这是前置原型,但是在C++中则说明该函数没有参数。也就是说,在C++中,intslice();和int slice(void);相同。例如,下面旧风格的代码在C中可以接受,但是在C++中会产生错误:

int slice();
int main()
{...slice(20, 50);...
}
int slice(int a, int b)
{...
}

在C中,编译器假定用户使用旧风格声明函数。在C++中,编译器假定slice()与slice(void)相同,且未声明slice(int,int)函数。

另外,C++允许用户声明多个同名函数,只要它们的参数列表不同即可。

3、char常量

C把char常量视为int类型,而C++将其视为char类型。例如,考虑下面的语句:

char ch = 'A';

在C中,常量'A'被储存在int大小的内存块中,更精确地说,字符编码被储存为一个int类型的值。相同的数值也储存在变量ch中,但是在ch中该值只占内存的1字节。

在C++中,'A'和ch都占用1字节。它们的区别不会影响本书中的示例。但是,有些C程序利用Char常量被视为int类型这一特性,用字符来表示整数值。例如,如果一个系统中的int是4字节,就可以这样编写C代码:

int x = 'ABCD'; /*对于int是4字节的系统,该语句出现在C程序中没问题,但是出现在C++程序中会出错 */

'ABCD'表示一个4字节的int类型值,其中第1个字节储存A的字符编码,第2个字节储存B的字符编码,以此类推。注意,'ABCD'和"ABCD"不同。前者只是书写int类型值的一种方式,而后者是一个字符串,它对应一个5字节内存块的地址。考虑下面的代码:

int x = 'ABCD';
char c = 'ABCD';
printf("%d %d %c %c\n", x, 'ABCD', c, 'ABCD');

在我们的系统中,得到的输出如下:

1094861636 1094861636 D D

该例说明,如果把'ABCD'视为int类型,它是一个4字节的整数值。但是,如果将其视为char类型,程序只使用最后一个字节。在我们的系统中,尝试用%s转换说明打印'ABCD'会导致程序崩溃,因为'ABCD'的数值(1094861636) 已超出该类型可表示的范围。

可以这样使用的原因是C提供了一种方法可单独设置int类型中的每个字节,因为每个字符都对应一个字节。但是,由于要依赖特定的字符编码,所以更好的方法是使用十六进制的整型常量,因为每两位十六进制数对应一个字节。第15章详细介绍过相关内容(C的早期版本不提供十六进制记法,这也许是多字符常量技术首先得到发展的原因)。

4、const限定符

在C中,全局的const具有外部链接,但是在C++中,具有内部链接。也就是说,下面C++的声明:

const double PI = 3.14159;

相当于下面C中的声明:

static const double PI = 3.14159;

假设这两条声明都在所有函数的外部。C++规则的意图是为了在头文件更加方便地使用const。如果const变量是内部链接,每个包含该头文件的文件都会获得一份const变量的备份。如果const变量是外部链接,就必须在一个文件中进行定义式声明,然后在其他文件中使用关键字extern进行引用式声明。

顺带一提,C++可以使用关键字extern使一个const值具有外部链接。所以两种语言都可以创建内部链接和外部链接的const变量。它们的区别在于默认使用哪种链接。

另外,在C++中,可以用const来声明普通数组的大小:

const int ARSIZE = 100;double loons[ARSIZE]; /* 在C++中,与double loons[100];相同 */

当然,也可以在C99中使用相同的声明,不过这样的声明会创建一个变长数组。在C++中,可以使用const值来初始化其他const变量,但是在C中不能这样做:

const double RATE = 0.06;            // C++和C都可以const double STEP = 24.5;            // C++和C都可以const double LEVEL = RATE * STEP;    // C++可以,C不可以

5、结构和联合

声明一个有标记的结构或联合后,就可以在C++中使用这个标记作为类型名:

struct duo{    int a;    int b;};struct duo m; /* C和C++都可以 */duo n; /* C不可以,C++可以*/

结果是结构名会与变量名冲突。例如,下面的程序可作为C程序编译,但是作为C++程序编译时会失败。因为C++把printf()语句中的duo解释成结构类型而不是外部变量:

#includefloat duo = 100.3;int main(void){    struct duo { int a; int b;};    struct duo y = { 2, 4};    printf ("%f\n", duo); /* 在C中没问题,但是在C++不行 */    return 0;}

在C和C++中,都可以在一个结构的内部声明另一个结构:

struct box
{struct point {int x; int y; } upperleft;struct point lowerright;
};

在C中,随后可以使用任意使用这些结构,但是在C++中使用嵌套结构时要使用一个特殊的符号:

struct box ad;          /* C和 C++都可以 */
struct point dot;       /* C可以,C++不行 */
box::point dot;         /* C不行,C++可以 */

6、枚举

C++使用枚举比C严格。特别是,只能把enum常量赋给enum变量,然后把变量与其他值作比较。不经过显式强制类型转换,不能把int类型值赋给enum变量,而且也不能递增一个enum变量。下面的代码说明了这些问题:

enum sample {sage, thyme, salt, pepper};enum sample season;season = sage;              /* C和C++都可以 */season = 2;                 /* 在C中会发出警告,在C++中是一个错误 */season = (enum sample) 3;   /* C和C++都可以*/season++;                   /* C可以,在C++中是一个错误 */

另外,在C++中,不使用关键字enum也可以声明枚举变量:

enum sample {sage, thyme, salt, pepper};
sample season;    /* C++可以,在C中不可以 */

与结构和联合的情况类似,如果一个变量和enum类型的同名会导致名称冲突。

7、指向void的指针

C++可以把任意类型的指针赋给指向void的指针,这点与C相同。但是不同的是,只有使用显式强制类型转换才能把指向void的指针赋给其他类型的指针。下面的代码说明了这一点:

int ar[5] = {4, 5, 6,7, 8};int * pi;void * pv;pv = ar;            /* C和C++都可以 */pi = pv;            /* C可以,C++不可以 */pi = (int * ) pv;   /* C和C++都可以 */

C++与C的另一个区别是,C++可以把派生类对象的地址赋给基类指针,但是在C中没有这里涉及的特性。

8、布尔类型

在C++中,布尔类型是bool,而且ture和false都是关键字。在C中,布尔类型是_Bool,但是要包含stdbool.h头文件才可以使用bool、true和false。

9、可选拼写

在C++中,可以用or来代替||,还有一些其他的可选拼写,它们都是关键字。在C99和C11中,这些可选拼写都被定义为宏,要包含iso646.h才能使用它们。

10、宽字符支持

在C++中,wchar_t是内置类型,而且wchar_t是关键字。在C99和C11中,wchar_t类型被定义在多个头文件中(stddef.h、stdlib.h、wchar.h、wctype.h)。与此类似,char16_t和char32_t都是C++11的关键字,但是在C11中它们都定义在uchar.h头文件中。

C++通过iostream头文件提供宽字符I/O支持(wchar_t、char16_t和char32_t),而C99通过wchar.h头文件提供一种完全不同的I/O支持包。

11、复数类型

C++在complex头文件中提供一个复数类来支持复数类型。C有内置的复数类型,并通过complex.h头文件来支持。这两种方法区别很大,不兼容。C更关心数值计算社区提出的需求。

12、内联函数

C99支持了C++的内联函数特性。但是,C99的实现更加灵活。在C++中,内联函数默认是内部链接。在C++中,如果一个内联函数多次出现在多个文件中,该函数的定义必须相同,而且要使用相同的语言记号。例如,不允许在一个文件的定义中使用int类型形参,而在另一个文件的定义中使用int32_t类型形参。即使用typedef把int32_t定义为int也不能这样做。但是在C中可以这样做。C允许混合使用内联定义和外部定义,而C++不允许。

13、C++11中没有的C99/C11特性

虽然在过去C或多或少可以看作是C++的子集,但是C99标准增加了一些C++没有的新特性。下面列出了一些只有C99/C11中才有的特性:

指定初始化器;

受限指针(Restricted pointer) (即,restric指针);

变长数组;

伸缩型数组成员;

带可变数量参数的宏。

b9e4cb1cf04c2d5e4aa37e2713958d66.gif

如果你年满18周岁以上,又觉得学【C语言】太难?想尝试其他编程语言,那么我推荐你学Python,现有价值499元Python零基础课程限时免费领取,限10个名额!
▲扫描二维码-免费领取

da4ef6ae1ad55aa619b58d7a3e5a0843.gif

戳“阅读原文”我们一起进步

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

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

相关文章

postgresql两个列模糊比较_数据分析之SQL优化系列(二)---PostgreSQL 的索引

参考《PostgreSQL11.2-中文手册》下面这个链接,讲的通俗易懂,可以看看。数据分析师不得不知道的SQL优化 - 鑫获 - 博客园​www.cnblogs.com索引是提高数据库性能的常用途径。比起没有索引,使用索引可以让数据库服务器更快找到并获取特定行。但…

高达 36 斤的 C/C++ 编译器?

点击蓝字关注我们来源于网络,侵删前言软件有重量吗?有人说,现代的软件主要搭载在硬件之上,只有占用内存的大小;也有人说,软件都是在网络上下载下来的,哪有什么重量可言;还有人说&…

双屏全屏跳回到主屏_双屏笔记本了解下?剪视频不要太好使

[PConline 评测]每天一开始上班,我们就要开始跟各种电脑程序和窗口打交道,而当面对各种信息和数据的轰炸时,恨不得就要把ALTTAB两个键给磨烂了。↑每天至少要面对十多个窗口gif而今天,笔记本厂商也不再吝啬于给予用户更多更大的屏…

一例看懂C语言程序中的内聚和耦合

点击蓝字关注我们来源自网络,侵删一、原理篇(清楚相关原理的读者,请直接看第二部分示例篇)在软件工程中,模块的内聚和耦合是度量模块化质量的标准之一。内聚是指模块的功能强度的度量,即一个模块内部各个元…

openfire消息通知推送_APP消息推送功能之前端后台设计

APP消息推送功能之前端后台设计最近有不少小伙伴问APP消息推送功能,前端、后台如何设计的?消息系统的架构是什么样的?最近刚好做到后台消息推送这块,简单谈谈个人心得,欢迎拍砖。消息推送是让自己的用户获取信息最有效…

apache spark_Apache Spark:更改架构之前必须解决的5个陷阱

apache spark迁移到Apache Spark之前需要了解的5件事 似乎每个人都只是在谈论最热门的新技术,而忽略采用它的实际含义。 但这是自然的,对吧? 新功能和承诺胜过其他所有事物,而艰难的挑战和决​​定被抛在一边。 这次不行。 软件…

分步解析C++实现通讯录管理系统

点击蓝字关注我们来源于网络,侵删一、前言建议亲手写一遍代码,感受指针神奇的魅力;可以帮助你更好的巩固知识体系,熟悉指针,结构体与函数一起使用时的妙处完成通讯录管理系统所需知识体系结构体指针函数的封装指针与函…

如何用C++实现动态放烟花(附源码)

点击蓝字关注我们来源于网络,侵删一、前言C实现的放烟花程序用到了EGE图形库,没有的需要自行安装可调项:背景图和背景音乐、粒子模糊度、亮度以及上升速度的参数。实现的动态烟花非常好看,可以做给女朋友或者表白用,呵…

nginx哪个版本性能好_nginx性能为什么好

nginx在启动后,在unix系统中会以daemon的方式在后台运行,后台进程包含一个master进程和多个worker进程。我们也可以手动地关掉后台模式,让nginx在前台运行,并且通过配置让nginx取消master进程,从而可以使nginx以单进程…

metrics_FlexyPool如何支持Dropwizard Metrics包重命名

metrics介绍 FlexyPool严重依赖Dropwizard (以前称为Codahale)度量标准来监视连接池的使用情况 。 集成到Dropwizard中后,程序包名称必然会被重命名 。 因此,4.0.0版本将使用io.dropwizard.metrics软件包名称代替com.codahale.me…

用C++写一个http服务器/web服务器

点击蓝字关注我们来源于网络,侵删本篇文章不会涉及到很多复杂的概念,也没有写很难读懂的模板函数,代码简单可读,本篇文章送给每一个想自己用C写一个http服务器的小伙伴!高手们、大佬们当然可以不用看的啦!正…

repl java9_Java 9抢先体验:与JShell进行动手实践– Java REPL

repl java9从今天开始,如何开始使用Java 9的最酷功能之一? 上周末,我终于开始尝试使用Java 9的早期访问版本。第一站是JShell,它也被称为Project Kulla。 首先让我鼓起勇气尝试早期访问Java版本的原因。 那就对了。 Java 9的正式…

java iterator获取索引_2020年Java面试题最新整理(1625)

16.Java集合框架是什么?说出一些集合框架的优点?每种编程语言中都有集合,最初的Java版本包含几种集合类:Vector、Stack、HashTable和Array。随着集合的广泛使用,Java1.2提出了囊括所有集合接口、实现和算法的集合框架。…

搞定红黑树(C++实现)

点击蓝字关注我们来源于网络,侵删红黑树的概念红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是红色或黑色。通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条…

java launcher_JAR清单类路径不仅适用于Java Application Launcher

java launcher自从我开始学习Java以来​​,我几乎已经知道, 清单文件中的Class-Path标头字段为可执行JAR (具有由另一个称为Main-Class清单指定应用程序起点的 JAR)指定了相对运行时类路径。 一个同事最近碰到一个让我感到惊讶&am…

C语言实现银行ATM存取款系统 | 附源码

点击蓝字关注我们来源于网络,侵删银行ATM存取款系统银行ATM存取款系统业务描述如下:银行ATM存取款系统能为用户提供存款、取款、查询、转账和修改密码的功能。为了模拟真实的ATM业务环境,本系统必须实现存款、取款、查询、转账、修改密码以及…

php 链接文件名_7、php-fpm进程管理

1、进程管理php-fpm采用的是master-worker的进程方式。其中,master负责fork worker进程;其次,注册信号,通过信号进行管理worker负责监听端口,等待链接,处理具体的逻辑如下图所示2、信号管理master进程可以理解如下信号…

C语言代码实现平衡二叉树|图解+详细代码

点击蓝字关注我们来源于网络,侵删1. 什么是平衡二叉树平衡二叉树,我们也称【二叉平衡搜索树/AVL】,树中任何节点的两个子树的高度最大差别为1,巴拉巴拉。。。(https://baike.baidu.com/item/AVL树/10986648?fraladdin)但是有个注意的点: 平衡…

cba比赛比分预测_【CBA直播】深圳vs广东前瞻:深圳战广东再掀反攻?

北京时间4月13日晚19点35分,CBA季后赛半决赛第三回合,深圳队主场迎战广东队。尽管目前双方总比分深圳以0-2落后对手,但他们在第二战的顽强表现给人留下了深刻印象。回归主场作战的他们,将在沈梓捷和贺希宁的带领下,力争…

C语言内存泄漏问题及其检视方法

点击蓝字关注我们来源于网络,侵删通过介绍内存泄漏问题原理及检视方法,希望后续能够从编码检视环节就杜绝内存泄漏导致的网上问题发生。本文通过介绍内存泄漏问题原理及检视方法,希望后续能够从编码检视环节就杜绝此类问题发生。预防内存泄漏…