第1个回答 2022-11-28
1、前言
在很大程度上,C++是C的超集,这意味着一个有效的C程序也是一个有效的C++程序。
C和C++的主要区别是:C++支持许多附加特性。但是,C++中有许多规则与C稍有不同。这些不同使得C程序作为C++程序编译时可能以不同的方式运行或根本不能运行。如果把C代码作为C++程序编译的话,会导致产生错误的消息。
C99标准的发布使得问题更加复杂,因为有些情况下使得C更接近C++。
例如,C99标准允许在代码中的任意处进行声明,而且可以识别//注释指示符。在其他方面,C99使其与C++的差异变大。
例如,新增了变长数组和关键字restrict。C11缩小了与C++的差异。
我们要了解C90、C99、C11之间的区别,还要了解C++11与这些标准之间的区别,以及每个标准与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类型这一特性,用字符来表示整数值。
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解释成结构类型而不是外部变量:
#include
float 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类型的同名会导致名称冲突。
第2个回答 2017-06-21
一:C语言。C语言诞生得非常早,当时人们普遍还习惯用汇编语言编写软件,而且没有什么统一,通用的操作系统,基本上软件都是从0开始写的。C语言的目标就是比汇编方便易用,同时不要损失汇编的表达能力。所以C语言可以看成是“高级的汇编”语言。C语言的源代码基本上可以非常容易地对应到汇编代码,而且可以不需要什么运行时环境的支持。C的特点,简单容易编译,灵活贴近底层。
二:C++ 语言。C++早期是基于C的,C++早期的编译方法是将C++的代码编译成C代码然后再调用C的编译器来生成机器码。C++的目标是提高编程人员的生产率,哪怕代价是增加编译器的复杂度。而提高编程人员生产率的方法有如下几种:提高抽象层次,支持模块化编程,模块内紧耦合,模块间松耦合,自动化的代码生成等等,这些在C++中都有体现(“有体现”不是说只有C++能做这些,理论上C++能做的事情C和汇编都能做,“有体现”是指C++里面你可以更直接,更自然地做到这些)。面向对象只是C++的一部分,现代的C++的目标是支持多种编程范型,同时并不会离硬件太远。所以C++是非常适合写一些基础架构级软件的,比如编译器,GUI库等等。