1、指针的声明和初始化
声明指向特定类型的指针的格式:typeName * poiterName;
创建指针后,应将内存地址赋给它。
int ducks=12; //创建ducks变量,将值12存储在在该变量中。
int *birddog=&ducks; //创建指针变量birddog,将ducks的地址存储在该变量中。
将一个指针初始化为一个地址:
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int a=6;
int *b=&a;
cout<<"Address of a:"<<&a<<endl;
cout<<"Address of b:"<<b<<endl;
return 0;
}
程序将b(而不是*b)初始化为a的地址。
对指针解除引用,其实就是获得指针的值(如:*b)。
2、使用指针的注意点
(1) 在C++创建指针时,计算机将分配用来存储地址的内存,但不会分配用来存储指针所指向的数据的内存。故必须赋给创建的指针一个明确的内存地址。
如:
int * a; //create an empty pointer
*a=5; //this pointer store in where?just place a value in a unsure land
Be care for ! It's dangerous and easy to make mistakes!!!
(2)同数组!不要指向一个未被初始化的数组下标中去,这将导致意想不到的错误。
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int * pt=new int [10];
pt[0]=1;
pt[1]=2;
pt[2]=3;
cout<<"pt[1] ="<<pt[1]<<endl;
pt=pt+1;
cout<<"now pt[0]="<<pt[0]<<endl;
cout<<"pt[1]="<<pt[3]<<endl;
pt=pt-1;
delete [] pt;
return 0;
}
(3)地址不一定是int型的,故需要对地址进行强制类型转换。
int *pt;
pt=0xB8000000; //type mismatch .
pt=(int *)0xB000000; //type now match.
(4)
int a[10];
a[1]=1;
*(a+2)=2; //the same to a[2]
(5)在C++中,用引号括起来的字符串像数组名一样,也是第一个元素的地址。
const char *bird="wren";//bird holds address of string
(6)新创建的空指针,使用赋值法和使用strcpy()赋值的区别
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
char animal[20]="bear";
const char * bird="wren";
char * ps;
cout<<"animal:"<<animal<<"and\n";
cout<<"bird:"<<bird<<"\n";
//cout<<" ps:"<<ps;
cout<<"Enter a kind of animal:";
cin>>animal;
//cin>>ps;
ps=animal;
cout<<"ps:"<<ps<<endl;
cout<<"Before using strcpy():\n";
cout<<animal<<" at "<<(int *)animal<<endl;
cout<<ps<<" at "<<(int *)ps<<"\n";
ps=new char[strlen(animal)+1];
strcpy(ps,animal);
//ps=animal;
cout<<"After using strcpy():\n";
cout<<animal<<" at "<<(int *)animal<<endl;
cout<<ps<<" at "<<(int *)ps<<endl;
//delete [] ps;
return 0;
}
使用赋值语句给指针赋值,实际是将数组的地址和数值传递给了指针,使该指针任然指向该地址。使用strcpy()语句,会重新分配一个独立的地址,然后将值传递给指针,使指针指向该独立的地址。
3、使用new和delete
(1)为一个数据对象(可以是结构,也可以是基本类型)获得并指定分配内存的通用格式:
typename pointer_name=new typename;
如:int * pt=new int;
long *pd=new long;
(2)创建指针时,会分配内存空间来指向存储的内存地址。可以使用delete来释放指针指向的地址,但不会删除指针本身。
如:int *pt=new int; //allocate memory with new;
delete pt; //free memory with delete when done;but will not delete itself,you can point it to a new allocate memory
(3)为数组分配内存的通用格式:
type_name pointer_name=new type_name [num_elements];
如:int * psome=new int [3]; //new操作符返回第一个元素的地址,该地址被赋给指针psome,故psome指向数组的第一个元素的地址,*psome是第一个元素的值。
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int * pt=new int [10];
pt[0]=1;
pt[1]=2;
pt[2]=3;
cout<<"pt[1] ="<<pt[1]<<endl;
pt=pt+1;
cout<<"now pt[0]="<<pt[0]<<endl;
cout<<"pt[1]="<<pt[1]<<endl;
pt=pt-1;
delete [] pt;
return 0;
}
使用delelte的注意事项:
(1)delete只能用于释放由new分配的内存;
(2)对空指针使用delete是安全的;
(3)不要尝试释放已经释放的内存,即不要使用delete删除同一个内存块两次。
(4)使用new []分配的内存,需使用delete []来释放;
(5)不要创建两个指向同一个内存块的指针,因为这将增加错误地删除同一个内存块两次的可能性。
如果new分配的内存没有使用delete进行释放,则会发生内存泄漏(memory leak),也就是被分配的内存再也无法使用了。如果内存泄漏严重,则程序将由于不断寻找更多内存而终止。
指针和对象小结:
- 使用常规表示法来声明指向对象的指针:String * glamour;
- 可以将指针初始化为指向已有的对象:String * first=&sayings[0];
- 可以使用new来初始化指针,这将创建一个新的对象:
-
//invokes default constructor String * gleep=new String; //invokes the String(const char *) constructor String * glop=new String("my my my"); //invokes the String(const String &) constructor String * favorite=new String(sayings[choice]);
- 可以使用->操作符通过指针访问类方法:if(sayings[i].length()<shortest->length())
- 可以对对象指针应用解除引用操作符(*)来获得对象:
if(sayings[i]<*first) first=&sayings[i]; //assign object address