c++primer plus复合类型之指针

指针是一个变量,其存储的是值的地址,而不是值本身。

了解:在讨论指针之前,我们先看一看如何找到常规变量的地址,只需对变量应用地址运算符&,就可以获得他的位置,例如

int cups=6;
double donuts=4.5;
cout<<"cups value="<<cups<<endl;
cout<<"and cups adress="<<&cups<<endl;
cout<<"donuts value="<<donuts<<endl;
cout<<"and donuts adress="<<&donuts<<endl;
程序输出:

cups value=6
and cups adress=0x0065fd40
donuts value=4.5
and donuts adress=0x0065fd44

1:指针概念

使用常规变量时,值是指定的量,而地址为派生量。对于指针策略来说,将地址视为指定的量,而值视为派生量。因此,指针名表示的是地址,*运算符被称为间接值或解除引用运算符,将其用于指针,可以得到该地址处的值。例如,假设manly是一个指针,则manly表示的是一个地址,而*manly表示存储在该地址处的值。*manly和 常规int变量等效。

2:指针的声明和初始化指针

声明指针的句法:typeName* pointer_name;例如,int* p_update;声明了一个int* 类型的指针,int*是一种复合类型,是指向int的指针。还可以声明例如,char* str;声明了一个char* 类型的指针。注意:在这里,p_update和str指向了两种长度不同的数据类型,但这两个指针变量本身的长度通常是相同的,也就是说,char的地址和int的地址的长度相同,一般来说,地址需要2个或是4个字节,这取决于计算机系统。

初始化指针:初始化的是指针而不是它指向的值。例如,int cups=6;   int* pt=&cups;这里将pt(而不是*pt)的值设置为&cups

下面程序演示了指针的声明和初始化

#include <iostream>
using namespace std;
int main()
{
	int higgen=5;
	int* pt=&higgen;

	cout<<"value of higgen="<<higgen
	<<";Address of higgen="<<&higgen<<endl;
	cout<<"value of *pt="<<*pt
		<<";value of pt="<<pt<<endl;
	return 0;
} 
输出:value of higgen=5;Address of higgen=00F3FD40; value of *pt=5;value  of pt=00F3FD40;

从中可以知道,程序将pt(而不是*pt)初始化higgen的地址。
3:指针的危险

long* fellow;
*fellow=10000;
上述代码确实定义了一个fellow指针,但是它没有确定的指向,因为没有将地址赋给fellow。那么10000将被放置在哪里存在不确定性,这种不确定性,可能会导致一些难以追踪的bug。

警告:一定要在对指针应用解除引用运算符(*)之前,将指针初始化为一个确定的、适当的地址。
4:指针和数字

指针不是整型,虽然计算机通常把地址当做整型来处理。他们两者是截然不同的概念,整型可以执行加减乘除等运算的数字,而指针描述的是位置,将两个地址相乘没有意义,因此,不能简单地将一个整数值赋给指针,例如,下面的语句是不合法的:

int* pt;
pt=0xB8000000;
要将数字值作为地址使用,必须进行强制类型转换,例如

int* pt;
pt=(int*)0xB8000000;
5:使用new来分配内存

对指针有一定了解之后,了解一下它是如何实现在程序运行时分配内存的。前面描述的指针声明方法,只是为可以通过名称直接访问内存提供了一个别名。指针的真正用武之地在于,在运行阶段分配未命名的内存以存储值。在这种情况下,可以通过指针访问内存。在c++中,使用new运算符来分配内存。

举个栗子:int* pn =new int ;在这里,运行阶段为一个int值分配未命名的内存,并使用指针来访问这个值。这里的关键所在是c++的new运算符,程序员要告诉new,需要为哪种数据类型分配内存:new将找到一个长度正确的内存块,并返回该内存块的地址。程序员的责任是将该地址赋给一个指针。就这个例子来说,new int告诉程序,需要适合存储int的内存。new运算符将根据类型来确定需要多少字节的内存。然后,它找到这样的内存,并返回其地址,接下来,将地址赋给pn,pn被声明为指向int的指针。现在,pn是地址,*pn是存储在pn里的值。

为一个结构或基本类型获得并指定分配内存的通用格式:typeName* pointer_name = new typeName;

对于指针,需要指出的另一点是,new分配的内存块通常与常规变量声明分配的内存块不同。new从被称为堆或自由内存区的内存区域分配内存,而普通变量值存储在成为栈的内存区域内。

6:使用delete释放内存

当需要内存时,可以使用new来请求,另一方面是delete运算符,它使得在使用完内存块时,能够将其还给内存池,这是最有效使用内存的关键。归还或释放的内存可供程序的其他部分使用。使用delete时,后面要加上指向内存块的指针这些内存块最初是由new分配的)。

int* ps = new int ;
...
delete ps;
这将释放ps指向的内存,而不会删除ps指针本身,还可以在后续程序中,将ps重新指向新的内存区。 一定要配对使用new和delete。 另外,不能使用delete来释放声明变量所获得的内存区。

例如,下面写法是不合法的:

int juge = 10 ;
int* ps=&juge;
delete ps;
警告:只能使用delete来释放使用new分配的内存。

7:使用new来创建动态数组

方法,只需要将数组的元素类型和元素数目告诉new即可。必须在类型名后加上方括号,其中包含元素个数。例如,

int* ps = new int[10];
new运算符返回数组的首地址,赋给指针ps。当程序使用完new分配的内存后,应使用delete释放内存区,但是需要使用另一种形式的delete来释放。例如,

delete [] ps ;
方括号告诉程序,应释放整个数组。 注意,使用new时,不带方括号,则delete释放时也不带方括号,使用new时,带方括号,则delete释放时也带上方括号。
8:使用动态数组

要如何访问动态数组中的元素呢?只要把指针当做数组名使用即可,即对于第一个元素,可以使用ps[0],对于第二个元素,可以使用ps[1],以此类推。例如,

#include <iostream>
using namespace std;
int main()
{
	int* pt=new int [3];//创建动态数组
	pt[0]=0;
	pt[1]=1;
	pt[2]=2;
	cout<<"pt[0]="<<pt[0]<<endl;
	pt=pt+1;
	cout<<"now,pt[0]="<<pt[0]<<endl;
	cout<<"pt[1]="<<pt[1]<<endl;
	pt=pt-1;
	delete [] pt;//释放数组
	return 0;
} 
输出结果:

ps[0]=0;

now,ps[0]=1;

ps[1]=2;




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值