最近在看 中科院的 c++ 程序设计 对比以前自己学的 以前太肤浅了
从网上看到 一篇关于 《指针的指针、数组指针以及指针数组》文章写得很好, 学习了。
搞清指针的四方面内容:
1.指针的类型
2.指针所指向的类型
3.指针的值或者叫指针所指向的内存区
4.还有指针本身所占据的内存区
指针的类型:
从语法的角度看,你只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型,这是指针本身所具有的类型。例如:
(1)int *ptr; //指针的类型是 int * 整型指针
int i;
ptr=&i;
(2)int **ptr; //指针的类型是 int ** 指针的指针
int i;
int * pr=&i;
ptr=≺
(3)int (*ptr)[3]; //指针的类型是 int(*)[3] 数组指针
int array[2][3] = {{1,2,3},{4,5,6}};//二维数组看作是两个一维数组
int (*pa)[3]; //申明一个数组指针
//array[0]指代二维数组中{1,2,3}的首地址,那么&array[0]是数组指针型
pa = &array[0];
cout<<(*pa)[0]<<"|"<<(*pa)[1]< cout<<**pa< cout<<*(*pa+2)< pa++;
cout<<(*pa)[0]<<"|"<<(*pa)[1]< cout<<**pa< cout<<*(*pa+2)<
(4)int *ptr[3]; //指针的类型是 int*[3] 指针数组, 数组里面存放的是指针
int n1=10;
int n2=20;
int* np[2]={&n1,&n2};
cout<<*(np[0])< cout<<*(np[1]);//输出20
==================================================
char *name[ ] = {"Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday", "Sunday"};
cout<<"This is "<<name[week-1]<<endl;
(5)
char *nm = "Nice"; //变量指针
char name[ ] = "OK"; //常量指针
而cout<<name则用于读取该指针所指向的字符串内容。
指针所指向的类型:
(1)int *ptr; //指针所指向的类型是 int 指向整型
(3)int **ptr; //指针所指向的的类型是 int * 指向整型指针
(4)int (*ptr)[3]; //指针所指向的的类型是 int()[3] 指向个3维整型数组的指针
(5)int *ptr[3]; //指针所指向的类型是 int[] 指向指针数组的第一个单元
指针的值(又称指针所指向的内存区或地址):
指针的值是指针本身存储的数值,这个值将被编译器当作一个地址,而不是一个一般的数值。在32位程序里,所有类型的指针的值都是一个32位整数,因为32位程序里内存地址全都是32位长。指针所指向的内存区就是从指针的值所代表的那个内存地址开始,长度为sizeof(指针所指向的类型)的一片内存区。以后,我们说一个指针的值是XX,就相当于说该指针指向了以为首地址的一片内存区域;我们说一个指针指向了某块内存区域,就相当于说该指针的值是这块内存区域的首地址。
指针本身所占据的内存区:指针类型本身占据的内存空间,在32位平台中,指针本身占据4个字节的长度,可以使用sizeof(指针类型)来测试下指针占据的存储空间。
指针的指针:这个比较简单,如下代码1:指针pni指向整型变量ni,pni的值为ni所在内存中的地址,指针的指针ppni指向一个整型指针,ppni的值为指针pni所在的存储单元的地址。
int ni=10;
int* pni=∋
int** ppni=&pni;
数组指针:顾名思义,指向数组的指针,这里一定要区分指向数组首单元的指针和数组指针的区别。如下代码2:
int narr[3];
int *p=narr;
在以上代码中,narr只是一个指代数组首地址的指针,而不是一个指向数组的指针。所以p只是一个指向数组首地址的指针,。这个例子在《指针和数组名的区别》文章有详细介绍。
数组指针的使用见下代码3:
int array[2][3] = {{1,2,3},{4,5,6}};//二维数组看作是两个一维数组
int (*pa)[3]; //申明一个数组指针
//array[0]指代二维数组中{1,2,3}的首地址,那么&array[0]是数组指针型
pa = &array[0];
cout<<(*pa)[0]<<"|"<<(*pa)[1]< cout<<**pa< cout<<*(*pa+2)< pa++;
cout<<(*pa)[0]<<"|"<<(*pa)[1]< cout<<**pa< cout<<*(*pa+2)<
以上代码中第三行定义的pa是指向一个3维数组的数组指针。*pa就是一维数组的指针,自然可以使用(*pa)[i]的方式访问数组,而*pa+1则是(*pa)[1]这个元素的地址,所以自然得到第5,6,7行所注释的输出。经过pa++语句,由于pa是数组指针,后来pa中存放的地址应该是*pa+sizeof(array[0]),所以现在*pa就是一维数组{4,5,6}对应的首地址,同理得到第9,10,11行所注释的输出结果。
指针数组:也就是指针的数组,存放指针的数组,数组中的元素是指针。
例如:
int n1=10;
int n2=20;
int* np[2]={&n1,&n2};
cout<<*(np[0])< cout<<*(np[1]);//输出20
上述代码的第三行定义了一个指针数组,数组中含有两个元素,分别是n1、n2的地址,np[0],np[1]就是对应的这两个地址,所以*np[0],*np[1]分别是10,20
对于指针的指针、数组指针、指针数组,我们还可以给出更为直观的定义方法:
指针的指针:
typedef int* intP;
intP* p;
数组指针:
typedef int intArray[2];
intArray* p;
指针数组:
typedef int* intPtr;
intPtr p[2];
由于一些运算符优先级不同(*的优先级比[]低),所以在适当的时候使用typedef可以有效的避免迷惑性。