1.void型指针
int *x = malloc(sizeof(int) * 10);在C里面是合法的,但是在C++中编译不通过。从Bjarne Stroustrup给出的解释是这种类型是不安全的。就是说你可以使用一个void型的指针指向任何地址,如果你分配了一个地址给这个void指针指向另一个与它类型不同的指针,完全没有警告。
接着文章中又给出了一个例子。
int an_int;
void *void_pointer = &an_int;
double *double_ptr = void_pointer;
*double_ptr = 5;
当你分配了一个*double_ptr的值为5时,它在内存中占有了8个字节,但是int型的变量an_int只有四个字节大小。
2.指向数组的指针的分配和释放:new[] and delete[]
在C中,只有主要的一个内存分配函数:malloc。可以使用它给单个元素和数组分配空间:
int *x = malloc( sizeof(int) );
int *x_array = malloc( sizeof(int) * 10 );
释放资源:free( x );
free( x_array );
但是在C++中,对于数组的内存分配与单个元素的分配不同,我们要是用new[] and delete[]
int *x = new int;
int *x_array = new int[10];
delete x;
delete[] x;
一个简短的解释是,当你创建一个数组对象的时候,delete[]为数组中的每一个元素调用了析构函数,而delete并不这么做。
3.函数要先申明然后才能调用。
尽管大多数的c代码都遵从这个惯例,但是在C++中却是严格要求函数必须在使用之前申明。下面给出了一个在C中合法,但是在C++中非法的代码。
#include <stdio.h>
int main()
{
foo();
return 0;
}
int foo()
{
printf( "Hello world" );
}
4.在C中使用使用struct和enum
在C中我们必须要用关键字struct添加在用一个结构体去申明一个结构体对象的前面。在C++中我们可以使用如下代码:
struct a_struct
{
int x;
};
a_struct struct_instance;
这样我们就获得了一个a_struct类型的实例struct_instance。而在C中,我们在申明一个实例的时候,不得不多使用一个struct关键字。struct a_struct struct_instance;
事实上,在申明enum的时候也有一个相似的情形:在C中,我们也不得不多使用关键字enum去申明一个enum类型的实例。而C++中不需要这么做。作为一个注意点,大部分的C程序员都习惯使用typedef
typedef struct struct_name
{
/* variables */
} struct_name_t;
然后就可以用如下方式申明一个对象了
struct_name_t struct_name_t_instance;
但是有另一个应该告诉C++程序员的是:你仍然要使用struct struct_name这种语法来申明一个struct成员,相当于指向结构体得指针。(意思是说在一个结构体中申明一个另一个结构体的对象)
typedef struct struct_name
{
struct struct_name instance;
struct_name_t instance2; /* invalid! The typedef isn't defined yet */
} struct_name_t;
5.C++有一个更大的库
C++比C有一个大的多的库,而且当他们不是用C的时候会通过C++链接到别的地方。例如,如果你习惯于用g++来处理需要大量数据处理的话,当你使用gcc去编译c的时候,你就很吃惊的发现出现了上述的情况,你需要显示的包含math这个库来处理诸如sin 或者甚至sqrt:
% g++ foo.cc
or
% gcc foo.c -lm
6.没有布尔类型
C中没有提供一个本地的布尔类想。然而你可以使用enum来模仿一个布尔类型
typedef enum {FALSE, TRUE} bool;
7.main函数不会自动提供0作为返回值(return 0)
在C++中,你可以在main函数的末尾随便的丢掉return 0,这条语句,它会被自动的提供。
int main()
{
print( "Hello, World" );
}
但是在C中,你必须手动的添加:return 0
int main()
{
print( "Hello, World" );
return 0;
}