关于C和C++之间的过渡知识。
第一个C++程序
1 |
|
用new来分配空间
new
我们知道在C语言里用malloc()来分配内存;在C++仍然可以这样做,但C++有更好的办法——new运算符。
为一个数据对象(结构、基本类型等等)获得并指定分配内存的格式:1
2ElementType * pointer_name = new ElementType;
int *p1 = new int;
那么,这两种方法,将变量的地址赋给指针,有什么区别呢?
1 |
|
第一种情况是new将找到一个长度正确的内存块,返回该内存块的地址。
第二种情况下,可以用变量名a来访问该int,而第一种情况则只能通过指针来访问。
乍一看,使用new方法处理数据可能不太好用(p1指向的“东西”没有名称),但是它使得程序在管控内存方面有更大的控制权。
如果像这样,程序只需要一个值,或者一个简单的变量,这样的管理一个小型数据对象来说,直接声明比new或者指针更简单(此时的指针不让人印象深刻)。通常,对于大型数据(如字符数组、结构),应该使用new和指针,这正是指针的用武之地。
使用delete释放内存
1 |
|
内存被耗尽?
可能由于没有足够的内存满足new的要求,这种情况下,new函数将会有错误处理。在较老的实现中,new将返回0,值为0的指针就是空指针(NULL)。C++确保空指针不会指向有效的数据,它常用来表示函数失败(如果成功,返回的是一个有用的指针)
内存泄漏?(memory leak)
1 | int *p1 = new int; |
这会释放p1的内存,但是不会删除p1本身。例如,delete p1后,可以对p1再使用new分配新内存。一定要配对使用new和delete,否则可能发生内存泄漏,也就是说,被分配的内存无法再被使用。如果这种情况严重,则程序将由于寻找不到内存而终止。
new创建动态数组
1 |
|
delete中的方括号告诉程序:释放整个数组。
new里有括号,delete就要带括号,new里没有,则delete也没有。
总之,使用new和delete的时候,遵守以下规则:(和malloc和free的原则有些许类似)
- 不要使用delete去释放不是new分配的内存。
- 不要对同一个内存块delete两次。
- 如果用new[],则应该使用delete[]。
- 如果用new(没有方括号),则应该使用delete(没有方括号)
- 对空指针使用delete是安全的。
函数与数组
在函数里声明数组:
1 | int sum_arr(int arr[], int n) |
这看似合理,方括号指明arr是一个数组,但实际情况是:arr实际上不是一个数组,而是一个指针。
这样是有好处的,将数组地址作为参数传递可以节省复制整个数组所花费的时间。而且如果数组很大,则使用拷贝时系统内存开销非常大。不仅需要占用很多内存,还需要很多时间去复制,还使得原始数据增加了被破坏的风险。
1 | int a[5] = {1,2,3,4,5}; |
上述代码输出结果是20、4、4。
const用法
用const保护数组数据
为了确保显示函数不修改数组原始数据,除非函数目的在此,否则应避免这种情况的发生。为防止函数无意中修改了数组的内容,可以在声明形参的时候使用关键字const
1 | void show_array(const double ar[], int n); |
假设函数更改了数组内容,编译器会报错。所以说,const主要是为了防止程序员的错误。
const与指针
const用于指针:
指向常量的指针
让该指针指向一个常量对象,这样可以防止用该修改指针来修改所指向的常量值。
1 | int a = 2, b = 4; |
常指针
将指针本身设置为常量,指针指向一个对象后,就一直效忠于这个对象。可以防止改变指针所指向的位置。
1 | int a = 2, b = 4; |
通用的方法:对于指针的定义语句,从右往左读。例如语句const int *p
就是:定义一个指向int型常量的指针。对于int const *p
,就是:定义一个常指针,指向一个int。
尽可能的使用const
将指针参数声明为指向常量数据的指针有两个好处:
1.这样可以避免无意间的修改而导致的错误。
2.使用const可以让函数处理const和非const形参,否则只能接受非const形参。