C与C++的差异

c/c++

浏览数:340

2019-10-16

c语言是结构化模块化的语言,是面向过程的程序设计。c++既可以面向过程,也可以面向对象的程序设计(增加了面向对象机制)。c语言的头文件都有.h后缀名,c++中用户自己编制的头文件带.h,系统提供的头文件无后缀名,c++兼容c的头文件。c语言的结构体struct只能包含数据成员,c++的类可以包含数据成员和成员函数。c++中使用usingnamespace作为命名空间,当含有系统头文件时必须包含命名空间。

相对于c语言,c++语言增加的主要特性包括类、重载、派生、虚函数、模板以及异常处理。 但在进一步讨论这些新特性之前,我们需要讨论这两种语言之间的一些小差异。

一、注释

c++语言支持单行注释。单行注释由//开始,在之后的第一个换行符处结束。单行注释比c语言的注释更安全,因为他们不会意外丢掉注释结束的标记,但c语言的注释在c++中任然是合法的。

二、标记与类型名

在c++语言中用于标识特定的结构、联合或枚举的名字会自动被认为是类型名。因此我们将

typedef struct {double re, im;} complex;

简单写成

struct complex  {double re, im;} ;

三、不带参数的函数

在声明和定义一个不带参数的c++函数时,可以不使用void:

void draw(void); //no arguments
void draw();        //no arguments either

四、默认实际参数
c++语言允许函数的实际参数有默认值。例如,下面的函数可以显示任意个数的换行符。如果调用时没有提供任何实际参数函数会显示一个换行符。

void new_line(int n=1)
{
    while (n-- > 0)
        putchar('\n');
}

调用new_line函数时,可以提供一个实际参数,也可以不提供实际参数。

new_line(3);  //print 3 blank lines
new_line();    //print 1 blank line by default

五、引用参数

c语言规定实际参数是按值传递的,这使编写那些需要修改作为实际参数提供的变量(除了数组)都非常困难。为了回避这个限制,我们只能传递指向该变量的指针。对于一个将两个变量的内容交换的函数,其C语言的实现大致如下:

void swap(int *a, int *b)
{
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
}

当swap函数被调用时,其参数应该是指向变量的指针:

swap(&i, &j);

虽然这种方式可以正常工作,但它使用起来并不方便,代码也不易理解,还容易出错。c++语言在这方面做一些改进,允许实际参数被声明成引用,而不是指针。下面是将a和b声明为引用后swap函数的样子:

void swap(int &a, int &b)
{
    int temp;
    temp = a;
    a = b;
    b = temp;
}

当swap函数被调用时,不需要在实际参数前加&运算符:

swap(i, j);

在swap的函数体中,a和b被分别理解为i和j的别名。语句temp=a确实会将i的值复制到temp中。语句a=b也确实将j的值复制到i中。同样,b=temp将temp的值复制给j。

当看到&a这样的形式时,怎样区别是声明引用变量还是取地址的操作呢?
请记住,当及a的前面有类型符时(如int &a),它必然是对引用的声明;如果前面没有类型符(如p= &a),此时的&是取地址运算符。

六、动态存储分配

c程序可以使用函数malloc、calloc、realloc动态分配和释放内存。虽然c++程序仍然可以使用这些函数,但更好的做法是使用new和delete。 new和delete是运算符,不是函数。new用来分配空间,delete用来释放分配的空间。new的操作数是一个类型说明符:

int *int_ptr , *int_array;
int_ptr = new int;
int_array = new int[10];

当无法分配所要求的内存时,new会返回空指针。delete需要用一个指针作为他的操作数:

delete int_ptr;
delete [ ] int_array;

七、输入输出

相比于c,c++增加了自己的输入输出流cin和cout(endl作为换行机制可以使用\n替换)。c中的scanf和printf为函数,而cin和cout为对象。cout不需要对输出数据进行格式控制,系统会自动按照数据类型输出;cin有一些格式控制功能。

八、函数的重载

c语言中,在同一作用域不能包含同名函数;c++中可以,这些同名函数中参数的个数或类型必须不同,返回值类型可以相同可以不同。(函数重载)

九、函数模板

函数的重载只是形参的类型或个数不同,也要分别定义。对此能否再简化呢?为了解决这个问题,C++提供了函数模板(function template)。所谓函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表。这个通用函数就称为函数模板。凡是函数体相同的函数都可以用这个模板来代替,不必定义多个函数,只须在模板中定义一次即可。在调用函数时系统会根据实参的类型来取代模板中的虚拟类型,从而实现了不同函数的功能。模板类声明如下:

template<class T>

类型参数可以不只一个,可根据需要确定个数。如template<class T1,typename T2>

T max(T a,T b,T c)   //定义一个通用函数,用T作虚拟的类型名
{
    if(b>a)a=b;
    if(c>a)a=c;
    return a;
}

十、总结

综上所述,c++对c功能的扩展包括:
(1)允许使用以“//”开头的注释。
(2)对变量的定义可以出现在程序中的任何行(但必须在引用该变量之前)。
(3)提供了标准输入输出流cin和cout,它们不用指定输入输出格式符(如%d),使输入输出更加方便。
(4)可以用const定义常变量。
(5)可以利用函数重载实现用同一函数名代表功能类似的函数,以方便使用,提高可读性。
(6)可以利用函数模板,简化同一类型的函数的编程工作。
(7)可以使用带默认值的参数的函数,使函数的调用更加灵活。
(8)提供变量的引用类型,即为变量提供一个别名,将“引用”作为函数形参,可以实现通过函数的调用来改变实参变量的值。
(9)增加了内置函数(内嵌函数),以提高程序的执行效率。
(10)增加了单目的作用域运算符::,这样在局部变量作用域内也能引用全局变量。
(11)可以用string类定义字符串变量,使得对字符串的运算更加方便。
(12)用new和delete运算符代替malloc和free函数,使分配动态空间更加方便。

作者:Leon_Geo