[指针]
指针定义:是一种数据类型跟int一样 int a,*b;整形的变量a,整形的指针变量b.
指针变量:是一种 变量,其中存放的值是指针类型的值 006E4000H(内存地址)
指针变量的定义与初始化
int a,*b;
char c;
b=&a;
int *c=&a;
char *d=&c;
一个指针变量在使用之前必须被赋值,否则指向不一定或者为0、空。
一个指针变量只能指向同一类型的变量;
当用一个变量的地址去初始化一个指针变量时,这个变量必须是已经定义过的;
不能把非地址量赋给指针变量;
空指针的值是0的指针,并不是值储存空间为空的意思,这里的0也不是数值的0,而是NULL字符的ASCII码值。不表示任何指向,只是指针变量的一种状态。Int *p=0;
两种特殊的运算符
*:指针运算符取内容运算符
&:取地址运算符
若p是指针变量;
那么*p 就是指针变量所指向的变量,是指针变量所指向的内存空间中的数据;
&p 指针变量所占储存空间的地址。
指针的算术运算
与普通整数的加减
p+n表示p当前所指位置向后第N个【数】内存地址,这里的【数】是与指针变量所指向的存储空间存储的值类型相同,所以如果*p是整数则向后数N乘以4字节,如果是char则向后数N乘以1字节
与指针的相减运算
((p)-(q))/数据长度
指针的自增,自减
指针的自增自减是(p+n)N为1的特殊情况
指针的关系运算
指针变量进行关系运算的前提是类型相同,否则都是没有意义,指针变量的关系运算表示他们所指向的变量在内存中的位置关系,若两个相类型的指针变量相等,就表示这两个指针变量指向同一块内存空间。
指针与一般整数常量关系运算也没有意义,但可以与整数0之间进行相等或不等的运算。
指针的赋值运算
把普通变量的地址赋给相同类型的指针变量。
int x,*P;p=&x;
具有相同数据类型的两个指针变量之间可以相互赋值
char *p,*q;p=q;
把数组的地址赋给具有相同数据类型的指针变量
double x[10],*p,*q;p=x;q=&x[2];
其他的常用赋值运算
int *p,*q,n;p=q+n;p=q-n;p+=n;p-=n;
[多级指针]
数据类型 **变量名;
int 1=5;int *p=&i;int **pp=&p;
则只有一级指针指向的变量才是要处理的变量,多级指针的数据类型是最终变量的类型。
[引用]
引用:就是某一个变量的一个别名
声明:数据类型 &引用名 = 目标变量名;int num;int &ref = num;//在声明的同时必须被初始化
说明:
& 在此是一个引用运算符,在此不再是进行求地址运算符,而是起标识作用,标志在此声明的是一个引用的名称。
数据类型既可以是系统的数据类型,也可以是用户自定义的对象
引用在声明时必须被初始化
引用声明完毕后,相当于有两个变量名,但是新声明的引用只表示目标变量的一个别名,所以系统不给引用分配存储单元,二是对应目标的的存储单元地址作为自己的地址,并且从此不改变,不能在定义为其他变量的别名,从一至终。
操作:
对引用求地址就是对目标变量求地址。
指针变量也是变量,可以声明一个指针变量的引用 数据类型 *&引用名=指针变量名;
int *a;int *&p=a; 对比求地址 int b;p=&a;//相当于a=&b,即将变量b的地址赋给指针变量a;
不能建立数组的引用(不同于指针);
引用本身不占存储单元,就不能声明引用的引用,也不能定义引用的指针;
不能建立空指针的引用 Int &n=NULL;
可以把函数的参数说明称引用,已建立函数参数的引用传递方式。
[指针与字符串]
在C/C++中春存一个字符串有两种办法
字符数组char s1[]="Hello world";
字符指针char *p="Hello world";这种形式下定义的字符串在内存中仍然与字符数组结构相同,即还是以字符数组存储。
字符指针char *p:p="Hello world";
但是 char *p;*p="Hello world";这是错误的,因为我们是把字符串常量的首地址存入p而不是把字符串存入p;
输出时cout<<p<<endl;即可输出字符串cout<<p[i]<<endl;即可输出特定空间的字母;
不管哪种存储方式字符串在存储时,都会在最后自动添加'/0',所以在输出时可以根据是否=='/0'来判断是否结束for(;*p!=0;p++)==for(int i;p[i]!=0;i++)
注 意:
在定义字符串指针变量时,可以直接用字符串常量座位初始值对其进行初始化 char *p="Hello world";
在程序中可以直接把一个字符串常量赋值给一个字符指针变量char *p;p="Hello world";但数组却不能这样赋值char a[20];a="Hello world"错误;
字符指针变量不能是未经赋值或者初始化的无定向指针,它必须在程序中已经被初始化或把储存字符串常量的首地址赋给指针变量;否则无定向指针可能破坏程序,因为他可能指向存放指令或者数据的内存段;即char *p;cin>>p;是不正确的;
[指针与数 组]
int a[10];int *p;p=&a[0];或者p=a;p中存放数组元素的首地址也是数组第一元素的地址;
注意数组的存储位置是由系统分配的,是一个地址常量,一旦被初始化就不能更改,比如赋值自加自减
通过指针操作数组:
下标法,如a[i]或p[i];
指针法,如*(a+i)或*(p+i),可以*p++但不能*a++,a是地址常量;
对于一个数组元素a[i]的地址可以表示为:&a[i],p+i;a+i;
指针变量的运算:
(1)p++;
(2)*p++;由于*和++都是单目运算符,为同一个优先级,结合方向为从右向左所以等于*(p++);
(3)*(p++)跟*(++p);前者先取*p在p+1赋值给p,后者相反;
(4)(*p)++表示p所指向的值加1,即(a[0])++,如果a[0]=3;则执行a[0]++后,a[0]的值为4,p仍然指向a[0]。
(5)*p--相当于a[i--],*++p相当于a[++i],*--p相当于a[--i].
[指针数组]
数据类型 *指针数组名[元素个数];int *a[2];p[0],p[1]是两个指向整型数据的指针变量
初始化 :
指针数组指向多个变量
double a,b,c;double *p[]={&a,&b,&c};
指针数组中的每个元素都是一个指针,所以可以很方便指向另一个数组
int a[5]={1,2,3,4,5};int *p[]={&a[0],&a[1],&a[2],&a[3],&a[4]};
字符型指针数组的初始化时,可以使用字符串数组也可以使用字符串常量作为初始值
char s1[]="C++";char s2[]="php";char *p={s1,s2};
char *p2={"C++","php"};
使用字符指针数组处理多个字符串时,个字符串长度可以不相等,若利用二维数组处理多个字符串时,每一行的元素数都相等,如果按最长的字符串来定义列数,会浪费很多单元。
[数组指针]
确切的说是数组的指针
数据类型 (*指针变量类型)[元素个数];
int a[2][3]={1,2,3,4,5,6};
int (*p)[3];
int i,j;
p=a;//p=&a[0][0];
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
cout<<(*p)[j]<<"/t";//输出数组元素
}
p++;//转向下一行
}
1 2 3 4 5 6
[指针与二维数组]
Int a[3][2];int *p[3];p[0]=a[0];或者p[0]=&a[0][0];
二级指针处理二维数组
续上int **pp=&p;则*pp=a[0];*pp+1=a[1];*pp[2]=a[2];*(*pp+1)=a[0][1];**(pp+1)=a[1][0];*(*pp+1)+1=a[1][1];**(pp+2)=a[2][0];*((*pp+2)+1)=a[2][1];
其中*((*pp+i)+j)==p[i][j];
二级指针与字符串
char *a[]={"tianjin","beijing","shanghai",NULL};
char **pp;
pp=a;
while(*pp!=NULL)
{
cout<<*pp++<<endl;
}
【函数的指针】
定义:一个函数在编译时被分配一个入口地址(第一条指令的地址)可以将该地址非配给一个指针变量,这样,指针变量持有该函数入口地址,他就指向了该函数。
形式:数据类型 (*指针变量名) (形参类型);
[code]
int (*funp)(int a,int b);
int func(int a,int b){}
funp = func;//初始化
int result = *funp(1,2);//在此处*是程序控制转移到函数指针所指向的函数的入口地址.
[/code]
作用:主要体现在函数间传递涵数,也就是传递函数的执行地址。形参位可以接受函数的地址的函数指针变量,实参数为函数名。很有意思呀可以写出类似于PHP中的call_ user_func();
一个最简单的测试代码
[code]
[/code]
warning:函数指针是一个指向函数的指针变量,因此可以被多次赋值,只能指向函数的入口地址而不能只想函数的某一条指令.
【指针函数】
定义:返回值是指针的函数。
定义形式: 数据类型 * 函数名 (参数名) // int *pf(int x,int y);
函数返回的可以是变量的地址,数组的首地址,指针变量,还可以是结构体共用体等复合结构的数据类型的首地址。
warning :在程序中不使用数组名接受指针函数的返回值。