看到指针需要有几个概念:
1、其是个变量----------------------目的是要和常量区分开(常量诸如:地址)
2、本身类型是什么类型,指向对象是什么类型
看到指针有上面的概念,就能立足推理了:
-------------------------------------------------一维数组-------------------------------------------------------
下面我们来看下一段代码:
int a[5]={1,2,3,4,5};
int *p;
P=a;
只要学过指针的我想对于上面这段代码应该是感觉到非常简单,但是即便如此我们还是要仔细分析。
a:是一个有5个int类型的一维数组名,是这块一维数组的首地址(地址证明其实常量),是指向“列”(为了形象的描述)的(也即是指向单个元素的)。
a:是指向int元素的,其本身的类型是int *,因而可以p=a(类型赋值要两边一致)。
p;是个int*类型的变量,其指向的对象是int
只要明白了上面的基本概念我想遇到同类型的问题,都应该能够解决。
那么我想问&a你是否考虑过呢,它代表的值又是什么呢:
1 #include<stdio.h>
2 int main(){
3 int a[5]={1,2,3,4,5};
4 int *p;
5 p=a;
6 printf("%#x___%#x\n",&a,a);
7 return 0;
8 }
结果为:0xbfaad9d8___0xbfaad9d8
是不是发现很奇特,这个是数组的名的特别之处,但是a和&a代表的含义是不同的,&a是指向整个数组的,而a是指向数组长“列”成员的。
可以测试下:打印*((int *)(&a+1)-1)结果会是5
-------------------------------------------------一维数组-------------------------------------------------------
-------------------------------------------------二维数组-------------------------------------------------------
int a[2][3]={(10,1),2,3,4,5,6};
int (*p)[3] = a;或者是int *p[2]={a[0],a[1]};
分析:
a[2][3]----其数组名a表示整个二维数组块内存的首地址(是个常量),它本身是指向一个一个有三个int成员的一维数组,其类型是int (*)[3],因而可以int (*p)[3] = a ;
而a[0]则是*a,a[1]则是*(a+1),a[0],a[1]的本身的类型是int*,因而可以int *p[2]={a[0],a[1]},其指向的对象类型是int,即a[0],a[1]是指向一位数组“列“成员的,这里就是指向了单元素。
同样对于&a它是指向整个数组内存块的可以测试:*((int *)(*(&a+1))-1)打印结果会是6
可能有的人看不懂,我对*((int *)(*(&a+1))-1)分析下:
(&a+1)指向6后面(这应该没有异议对吧),*(&a+1)表示对地址”降级“(自己定义的概念,也即a->a[0]的过程),需要*(&a+1)类型的地址需要对齐进行强制(int *),转后(int *)(*(&a+1))-1表示当前这个地址指向6后面的一个字节减去sizeof(int),即指向6,再取值*((int *)(*(&a+1))-1)结果就是6.
-------------------------------------------------二维数组-------------------------------------------------------
通过上面的分析大家都应该对数组名有了深入的认识,数组名很特殊,所以在运用的时候要小心,避免出错