C与C++的区别

时间:2022-09-09 18:22:33

1 C与C++设计区别

C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现过程(事务)控制),而对于C++,首要考虑的是如何构造一个对象模型,让这个模型能够契合与之对应的问题域,这样就可以通过获取对象的状态信息得到输出或实现过程(事务)控制。
C实现了C++中过程化控制及其它相关功能,而在C++中的C(我称它为“C+”),相对于原来的C还有所加强,引入了重载、内联函数、异常处理(标准C中无此功能)等等,C++更是拓展了面向对象设计的内容,如类、继承、虚函数、模板和容器等等。 在C++中,数据封装、类型这些是最基本的,需要考虑的是诸如:对象粒度的选择、对象接口的设计和继承、组合与继承的使用等等问题。

2 语言上的变化

2.1 register变量

对于C而言不能通过&取地址符获得register变量的地址,但在C++中是可以的

//C++代码
register int a = 2;
cout << "&a = " << &a << endl;//OK

//C代码
register int a = 2;
printf("&a = %d\n", &a);//error

2.2 局部变量定义位置

C++中局部变量可以在程序块内任何地方定义,但是C语言中局部变量必须在程序块的开头定义(后来的C中取消了此限制,也可以在程序块的任何地方定义)

2.3 函数参数为空

在C++中func()等价于func(void),但是在C中func()既可以认为其有一个或多个参数,也可认为其没有参数,func(void)是表明没有参数的,如下代码:

//C++代码
#include <iostream>

using namespace std;

int func()
{
cout << "func()" << endl;
}

int main()
{
func();//正确
func(1);//错误
func('c');//错误
func(1,"dlkf");//错误

return 0;
}

//C 代码
#include <stdio.h>

int func()
{
printf("func()\n");
}

int main()
{
func();//正确
func(1);//正确
func('c');//正确
func(1,"dlkf");//正确

return 0;
}

2.4 字符常数

    //C代码
int a = "12"; //OK
printf("a = %d\n", a);

//C++代码
int a = "123"; //error

C语言中字符常数被当做整型处理(并不是指他所表示的整型),但C++中不行。

2.5 多次定义全局变量

int g;
int g;

以上代码在C中是可以接受的,但在C++中会报错(以上g为全局变量)

2.6 struct

struct myStruct
{
public:
void setX(int t)
{
x = t;
}
int getX()
{
return x;
}
private:
int x;
};

以上定义在C++中是可以的,在C中是不行的。
结构体是C的一部分,C++从C中继承了结构,在语法上,类与结构十分相似,在关系上,这两者也很接近,在C++中,结构的作用被拓宽了,进而使结构成为了类的一种替代方法.实际上,类与结构的惟一区别在于:在默认状态下,结构的所有成员均是公有的,而类的所有成员是私有的.除此之外,类与结构是等价的,也就是说,一个结构定义了一个类的类型. C++同时包含这两个等价的关键字struct与class基于3个方面的原因.第一,加强结构的能力.在C中,结构提供了一种数据分组方法,因而让结构包含成员函数是一个小小的改进.第二,由于类与结构是相互关联的,所有现有C代码到C++的移植变得更容易.第三,由于类与结构的等价性,提供两个不同的关键字可以使类定义*发展,为了保持C++与C的兼容性,结构定义必须始终受它的C定义的结束.

2.7 union

union myUnion
{
public:
void setX(int t)
{
x = t;
}
int getX()
{
return x;
}
private:
int x;
double y;
};

以上代码在C++中可以,但在C中是不可以的

联合也可以用来定义类.在C++中,联合包含成员函数,变量以及构造与析构函数.C++联合保留了C联合的全部特征,其中最重要的特征是所有数据元素共享内存的相同地址.与结构体类似,联合的成员在默认状态下也是公有的,并且完全兼容于C.与结构一样,C++中的联合声明定义了一种特殊的类,进而意味着保持了类的封装原则.
C++的联合有几个必须遵守的使用限制.
(1)联合不能继承其他任何类型的类.
(2)联合不能是基类,不能包含有虚函数成员.静态变量不能是联合的成员.联合不能使用引用成员,而且不能有任何作为成员的重载赋值运算符的对象.(3)如果一个对象包含明确的构造或析构函数,该对象不能成为联合的成员.

C++有一个叫做匿名联合的特殊联合.匿名联合没有类型名,也不声明任何变量,只是告诉编译程序它的成员变量共享一个内存地址.但是,变量本身无需要使用常规的点运算符语法即可直接引用.上述联合的使用限制也适用于匿名联合,但下面这两个限制除外,第一,匿名联合所包含的元素只能是数据,不能包含成员函数,也不能包含私有或受保护元素;第二,全局匿名联合必须声明成静态的.
注:以上struct和union部分参考了(尚有部分不是很理解具体用时回看)http://blog.csdn.net/wqvbjhc/article/details/4107268

2.8 引用类型(别名)

    int x = 2;
int& y = x;

在C++中y相当于x的别名,但是在C中没有这种表示会报错

2.9 异常处理

C++中加入try,catch异常处理机制,C中没有相应的机制。

2.10 内存操作

(1)malloc/free是C/C++的标准库函数,new/delete是C++的运算符
(2)malloc分配内存时需要指定大小(字节数),而new可以自动分配空间大小。
(3)new时做两件事,一是为分配内存空间,二是为分配的内存调用一个或多个构造函数构造对象;delete时也做两件事,一是调用一个或多个析构函数析构对象,二是释放内存空间。

C++引入new/delete的原因:
对于用户自定义对象,在对象创建时需要自动执行构造函数,在销毁之前需要自动执行析构函数,malloc/free是库函数不再编译器的控制权限之内,不能动态的管理对象,因此引入new/delete,new对对象完成动态内存分配和初始化,delete对对象完成清理和释放内存。

2.11 #define与inline, const

(1)#define宏定义是C中语法,它仅是进行简单的替换,不做安全性检查(比如参数类型,语法完整性等);inline是在编译时在调用点之间吧inline函数代码嵌入目标程序中,相比于普通函数少了中断调用速度更快,但是目标代码体积变大,inline具有安全性检查(比如参数类型,语法完整性等)。
(2)比如#define LEN 1+2,在代码中遇到LEN只是简单的用1+2替换掉LEN,看如下代码:

#include <iostream>

using namespace std;

#define TESTDEFINE1(x) x*x

inline int testInline1(int x)
{
return x*x;
}

#define TESTDEFINE2(x) ((x)*(x))

int main()
{
cout << "*******************test1**********************" << endl;
cout << TESTDEFINE1(1+2) << endl;
cout << testInline1(1+2) << endl;

cout << endl;
cout << "*******************test2**********************" << endl;
int x = 1;
cout << TESTDEFINE1(x++) << endl;
cout << "After TESTDEFINE1 x = " << x << endl;
int y = 1;
cout << testInline1(y++) << endl;
cout << "After testInline1 y = " << y << endl;
int z = 1;
cout << TESTDEFINE2(z++) << endl;
cout << "After TESTDEFINE2 z = " << z << endl;

return 0;
}

运行结果:
**************test1*****************
5
9

**************test2*****************
1
After TESTDEFINE1 x = 3
1
After testInline1 y = 2
1
After TESTDEFINE2 z = 3

(3)是否在调用点插入inline代码由编译器决定,编译器有权拒绝,inline函数体积一般比较小且被频繁调用。define与inline代码都在预编译器符号表中。
(4)定义常量尽量使用const代替#define定义的常量,因为#define没有类型检查等安全性检查,比如以下代码:

#define LEN1 1+2
const int LEN2 = 1+2;

cout << "LEN1*LEN1 = " << LEN1*LEN1 << endl; //输出5
cout << "LEN2*LEN2 = " << LEN2*LEN2 << endl; //输出9

(5)const, define定义常量的好处
a. 见名知义,比如以上LNE1,LEN2知道它们表示长度,而不是无意义的数字
b. 修改方便,若程序中多次使用到一个常量,我们若要修改其值只需修改一处
c. 提高运行效率,对于define使用预编译器进行的简单替换,不需要为常量分配空间,因此执行速度更快(const定义的常量,有的在符号表中,有的要分配空间)。