C++ 指针
指针的使用、使用new创建动态数组、使用delete释放内存
#include <iostream>using namespace std;// ----------------------------------指针-------------------------------------void pointer(){ int updates = 6; int * p_updates; p_updates = & updates; cout << "Value:updates = " << updates << endl; cout << "*p_updates = " << *p_updates << endl; cout << "Address:&updates = " << &updates << endl; cout << "p_updates = " << p_updates << endl; // 程序输出: // Value:updates = 6 // *p_updates = 6 // Address:&updates = 0xffffcbd4 // p_updates = 0xffffcbd4 // int变量updates和指针变量p_updates只不过是一枚硬币的两面。变量updates表示值,并使用&操作符来获得地址; // 而变量p_updates表示地址,并使用*操作符来取值,由于p_updates指向updates,因此*p_updates和updates // 完全等价。可以像使用int变量那样使用*p_updates。 // 指针的定义-*号操作符两边的空格是可选的 int *ptr; int* psr; // 每个指针变量的创建都需要一个*,下面的例子将创建一个指针p1和一个int变量p2 int *p1, p2; // 使用new关键字为指针分配内存 // 在C语言中可以使用库函数malloc()来分配内存,在C++中还有更好的方法——使用new操作符 int *pt = new int; // 内存耗尽 // 计算机可能会由于没有足够的内存而无法满足new的请求,在这种情况下,new将返回0,在C++中,值为0分指针 // 被称为空指针null pointer,C++确保空值指针不会指向有效的数据,因此它常被用来表示操作符或函数失效, // 如果成功,将返回一个有用的指针。 // 使用delete来释放内存 // 当需要内存时,可以使用new来请求,这只是C++内存管理数据包中有魅力的一个方面。另一个方面是delete操作符, // 它使得在使用完内存后,能够将其归还给内存池,这是通向最有效地使用内存的关键一步。归还或释放free的内存可供 // 程序的其他部分使用。使用delete时,后面要加上指向内存块的指针(这些内存块最初是用new分配的) // **注意:只能用delete来释放使用new分配的内存。不过对空指针使用DELETE是安全的。 // 这将释放ps指向的内存,但不会删除指针ps的本身,例如,可以将ps重新指向另一个新分配的内存块,一定要配对 // 地使用new和delete。否则程序将发生内存泄露memory leak,也就是说,被分配的内存再也无法使用了;如果 // 内存泄露严重,则程序将由于不断寻找更多内存而终止 int *p3 = new int; delete p3; // 不要尝试释放已经释放的内存块,C++标准指出,这样做的结果将是不确定的,这意味着什么情况都可能发生。另外 // 不能使用delete来释放声明变量所获得的内存; // int *p4 = new int; // delete p4; // delete p4; //not ok now,不能重复释放已经释放的内存块 // int jugs = 5; // int *p5 = &jugs; // delete p5; //不能delete来释放声明变量所获得的内存; // **注意,使用delete的关键在于,将他用于new分配的内存,这并不意味着要使用用于new的指针,而是用于new的地址 // 一般来说,不要创建两个指向同一个内存块的指针,因为这将增加错误地删除同一个内存块两次的可能性 // int *p6 = new int; // int *p7 = p6; // delete = p6; // 使用new创建动态数组 // 在C++中,创建动态数组很容易,只要将数组的元素类型和元素数目告诉new即可,必须在类型名后加上[],其中包含元素数目 int *psome = new int[10]; // new操作符返回第一个元素的地址,在这个例子中,该地址被赋给指针psome,当程序结束后,应使用DELETE释放 // 指针数组的使用 psome[0] = 0; psome[1] = 2; psome[2] = 3; cout << "psome[0] = " << psome[0] << endl; cout << "psome[1] = " << psome[1] << endl; cout << "psome[2] = " << psome[2] << endl; // psome[0] = 0 // psome[1] = 2 // psome[2] = 3 psome = psome + 1; cout << "psome[0] = " << psome[0] << endl; cout << "psome[1] = " << psome[1] << endl; // psome[0] = 2 // psome[1] = 3 // 指针返回到开始 psome = psome - 1; // 不能修改数组名的值,但指针是变量,因此可以修改他们的值。将psome + 1的效果,表达式psome[0]现在指向的是 // 数组的第二个值,因此将psome + 1导致它指向第二个元素而不是第一个。将它减一后,指针将指向原来的值 // 在释放new创建的动态数组时,应使用另一种格式的delete,它能够指出所要释放的是一个数组 // []会告诉程序,应释放整个数组,而不仅仅是指针指向的元素 delete[] psome; // 使用new和delete时,应遵守以下规则: // 1、不要使用delete来释放不是new分配的内存 // 2、不要使用delete释放同一个内存两次 // 3、如果使用new []为数字分配内存,则应使用delete[]来释放 // 4、如果使用new []为一个实体分配内存,则应使用delete来释放 // 5、对空指针应用delete是安全的 // 将指针变量加一后,其增加的值等于指向类型占用的字节数 // stacks[1]可以看作是* (stacks + 1),这意味着先计算第二个元素的地址,然后找到存储在那里的值。 // 最后输出存储在那里的值。 char flower[10]= "rose"; cout << flower << endl; cout << &flower << endl;}int main() { pointer(); return 0;}
使用new创建动态结构、使用delete释放new创建的动态结构的内存、使用->访问指针指向的结构体变量
#include <iostream>using namespace std;// 动态结构void structure(){ struct things{ int good; int bad; }; things grubonse = {3, 453}; things *pt = &grubonse; // 如果结构体标识符是结构名,则使用句点操作符 // 如果标识符是指向结构的指针,则使用箭头操作符 cout << "ps.good = " << pt->good << endl; cout << "ps.bad = " << pt->bad << endl; // 使用new创建结构体变量 person *person2 = new person; person2->name = "fc"; person2->age = 18; cout << "person2.name = " << person2->name << endl; cout << "person2.age = " << person2->age << endl; // 释放使用new创建的动态结构的空间 delete person2;}int main() { structure(); return 0;}
指针函数的定义、赋值、调用
// 定义指针函数// 指针函数声明时需要将*和函数名括起来,括号优先级比*操作符高,因此*fun (int)代表返回指针的函数,// 而(*fun) (int)意味着fun是一个指向函数的指针double pam(int);double (*pf) (int);// 指针函数的赋值,将pam函数的地址赋给pf,赋值函数和指针函数的返回值类型编写相同才能赋值// pf = pam;// 指针函数的调用double x = pam(3);double y = (*pf)(5);