个人网站www.v-ver.com

初学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]

对于数组来说也是一样的……

posted @ 2013-11-25 15:42  左光星  阅读(210)  评论(0编辑  收藏  举报
个人网站www.v-ver.com