初学C语言之指针:值类型和数组
指针博大精深,最近看一些非常基础的知识有很大感慨……
编译器:考级专用vc6.0
看了半天,总感觉有些地方非常迷糊首先看一下一个值int型的
#include<stdio.h> int main() { int a=0; //int* p=a; //这里报错,不能让一个int型的变量转为int*的指针变量 int* p=&a; printf("%p\n",p);//这里输出了a的地址 printf("%p\n",&p);//这里输出了指针变量p的地址 printf("%p\n",*(&p));//二者是互相逆转的操作,有没有括号无所谓 printf("%x\n",p);//这里是以16进制输出的地址,和上面唯一的差距是,上面是8位,也就说"%8x"同理 printf("%p\n",*p);//这里没有报错输出00000000其实就是0的表示 printf("%d\n",*p); return 0; }
p表示了一个地址,它是指针变量,而*p表示了a。
我们可以这么理解,*的意思是调用这个地址下的数据,&是调用这个数据的地址
很多人迷惑的地方其实就是这个定义。
int *a 与int* a,在执行时没有任何区别
但是,有很多人以为*p是一个int型的指针变量。
这是完全错误的,应该是p是一个int型的指针变量,请把(int*)当做一个类型,就可以理解。
这里告一段落,
下面是最有趣的,数组和指针的神似之处。
下面是数组;
#include<stdio.h> int main() { int a[20]={0}; int* p=a; int* pa=&a[0];//与上面等价 for(int i=0;i<10;i++) { printf("%p\n",p[i]);//*p[i]报错,这里输出了值00000000就是a[i] } //for(i=0;i<10;i++)与上面等价 //{ // printf("%p\n",pa[i]); //} printf("%p\n",&p[0]); printf("%p\n",&a[0]); printf("%p\n",&a);//这里其实相当于a[0] printf("%p\n",&pa[0]);//这里我们发现,四者的输出的东西是一样的 printf("%p\n",&p); printf("%p\n",&pa);//这里可以发现数字是不一样的 return 0; }
这里说明了什么,其实建立一个数组时,其实数组前的一个名字……其实它就是指针的意思,比如a[20]的a,其实它神似一个指针变量,叫做数组指针,当我把它的地址赋给p时,两者就没有任何区别。
包括pa,虽然看起来只是将a[0]的值给了它,其实效果是和前面一样的,而且a[20]的一些地址都会存在pa和p里面,pa,p任然独立存在,里面的内容任然是地址。
现在数组名字是一个比较屌的东西
继续上面的实验,加几行代码。
printf("%d\n",sizeof(a)); printf("%d\n",sizeof(p)); printf("%d\n",sizeof(pa));
好吧输出是80 4 4
这说明虽然数组名字任然代表了一个数组,我们可以得出这样一个结论
数组其实代表了一种数据结构,它本身包含了下面的所有地址的数据,它和指针有本质区别
但是它的外延其实是一个指针常量,注意是指针常量!
pa++; a++;//无法通过编译
刚才的实践……可以可以说明指向这个数组的一大堆货的2个指针p和pa,其实就是另外一种指针,注意!仅仅是指针!!只有4个字节。
下面讨论一些奇葩问题,如果把数组作为一个参数弄到函数里会怎样呢
#include<stdio.h> void wangji(int c[]); int wangji1(int c[]); int main() { int a[20]={0}; wangji(a); printf("%d",sizeof(a)); return 0; } void wangji(int c[]) { printf("%d\n",sizeof(c)); }
输出是4和80,数组作为形参到了函数里,就变成了一个指针。
最后还有一个好玩的东西
#include<stdio.h> int main() { int a=0; int* p=&a; printf ("%x\n",&a); printf ("%x\n",p); //前面两个是一样的 printf ("%x\n",p[0]); printf ("%x\n",p[1]); printf ("%x\n",p[2]); printf ("%x\n",p[3]); printf ("%x\n",p[4]); return 0; }
居然可以输出!没有报错.而且p[0]的地址不是p与a.
数据几乎没有什么规律,因为,printf,对于数组的输出,输出的实际上就是那个地址的值,所以这里非常相似!
我又做了一个事
#include<stdio.h> int main() { int a=0; int* p=&a; printf ("%x\n",&a); printf ("%x\n",p); printf ("%x\n",&p[0]); printf ("%x\n",&p[1]); printf ("%x\n",&p[2]); printf ("%x\n",&p[3]); printf ("%x\n",&p[4]); return 0; }
非常好,有顺序了,相差为4!
为什么?当我声明p的时候其实就可以说选取了一个节点,p[1]就相当于读取下一位。
神似之处,输出的方式非常相似!
总结
1、我可以这么说,数组是一种特殊的数据类型,它的外延是指针,但是这个指针是常量的。
2、我还可以这么说,指针可以当做一种没有初始化过的数组,因为p[i]可以依次读写数据。
3、指针只存储一个地址。(这里有待查证,不讨论指针数组)
4、一些基本知识 int* p
p是地址,p[0]是值。*p=p[0],p[1]的地址是这个东西&p[1]
对于数组来说也是一样的……