指针分很多种
int* arr=&a; 整型指针
char* ch=&b; 字符型指针
像这些都是指向整型,字符型的指针,arr储存整型的地址,ch储存字符型的地址。还有一种比较特殊的指针。
const char* ch=“abcdef”;
这是常量字符串,是无法被修改的。
总所周知,数组名是代表首元素地址
arr - 首元素地址
&arr - 数组的地址
存在差异,要牢记。
char arr1[]="abcdef";
char arr2[]="abcdef";
判断arr1是否等于arr2。
两个数组中储存的元素是一样的,但是,是在空间里创造了两个数组,分别是arr1和arr2。且,两个数组在内存中的地址是不一样的。而,我们知道数组名代表首元素地址,而两个数组在内存中的地址都不一样,则首元素地址也不一样。即不相等。
而下面的这就有点不一样了
const char* p1="abcdef";
const char* p2="abcdef";
看看这个。两个相同的字符串常量,无法被修改的。
而两个相同的字符串常量,在内存中只需储存一份即可。但是p1和p2却是相互独立的,在内存中创建了两个空间分别命名为p1,p2。而指针指向都是同一个地址。所以是相等的。
指针数组与数组指针
先来讨论指针数组
指针数组是数组,但储存的元素是指针,就是地址。
int* arr[4]; 存放整型指针的数组
char* pch[5]; 存放字符型的指针的数组
int a=10;
int b=20;
int c=30;
int* arr[3]={&a,&b,&c};//int*是代表元素的类型,指针类型。
还可以储存数组的指针
int arr1[]={1,2,3};
int arr2[]={2,3,4};
int arr3[]={3,4,5};
int* pch[]={arr1,arr2,arr3};
//数组名就是数组首元素的地址
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
printf("%d",*(pch[i]+j));
printf("%d",*(*(pch+i)+j));
}
}
- ((pch+i)+j)
pch可以看作一个数组,每个元素是,arr1.arr2,arr3。用(pch+i)解引用提取每个元素的名。pch+0,pch+1,pch+2,是数组跳过 。而数组名只是一个地址,pch里储存的也是地址,要把它提取出来,得到数组名,进入arr数组里在开始提取元素。
再来看看数组指针
是指针,指向数组的指针——存放数组的地址。
int arr[10];
arr-首元素地址
&arr[0]-首元素地址
&arr-数组的地址
[ ]的优先级比 * 高。
int (*p)[10]=&arr;
数组指针储存数组arr的地址。(*p)是表明是一个指针,而arr是一个储存10个元素的数组。要先了解每个都代表什么
int arr[5]; arr是一个整型数组,储存的每个元素都是int 整型。
int *arr[5];arr是一个指针数组,存储的每个元素都是指针类型,也就是地址。
int (*p)[5]=&arr,是一个数组指针,*p表明是一个指针,[5]代表指针p中储存的数组arr中有5个元素,而int表示5个元素都是int类型。
还有一个
int *(p)[5]=&arr
跟上面一样,只不过是int 类型,代表arr数组中储存的是指针类型,也是说都是地址。
像储存地址的,提取里面的地址,*p就等于数组名,也就是首元素 *p=arr,
(*p)[i]==arr[i],就像
int* p=&arr;
p==arr
arr[i]=p[i];
还有一个也是难理解
int (*p[10])[5]=int ( * ----- )[5]
--------------------------p[10]
是这样看的p是先和【】结合,是一个数组
int(* p)[10];p是一个数组指针,指向了一个有10个Int元素的数组。
和指针数组可以类比。
p是一个数组,p先于【】结合在于* 结合说明是一个储存10个指针的数组,而外面的 int (* )【5】,是指每个指针都指向一个有储存5个int 类型的数组。
总结一下,就是p是一个10个元素的数组,而每个元素都是一个指针,指向有5个元素都是int类型的数组。
确实有点难理解,我还要多悟悟。