zoukankan      html  css  js  c++  java
  • 初学C语言之指针:值类型和数组

    指针博大精深,最近看一些非常基础的知识有很大感慨……

    编译器:考级专用vc6.0

    看了半天,总感觉有些地方非常迷糊首先看一下一个值int型的

    #include<stdio.h>
    int main()
    {
        int a=0;
        //int* p=a; //这里报错,不能让一个int型的变量转为int*的指针变量
        int* p=&a;
        printf("%p
    ",p);//这里输出了a的地址
        printf("%p
    ",&p);//这里输出了指针变量p的地址
        printf("%p
    ",*(&p));//二者是互相逆转的操作,有没有括号无所谓
        printf("%x
    ",p);//这里是以16进制输出的地址,和上面唯一的差距是,上面是8位,也就说"%8x"同理
        printf("%p
    ",*p);//这里没有报错输出00000000其实就是0的表示
        printf("%d
    ",*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
    ",p[i]);//*p[i]报错,这里输出了值00000000就是a[i]
        }
        //for(i=0;i<10;i++)与上面等价
        //{
        //    printf("%p
    ",pa[i]);
        //}
        printf("%p
    ",&p[0]);
        printf("%p
    ",&a[0]);
        printf("%p
    ",&a);//这里其实相当于a[0]
        printf("%p
    ",&pa[0]);//这里我们发现,四者的输出的东西是一样的
        printf("%p
    ",&p);
        printf("%p
    ",&pa);//这里可以发现数字是不一样的
        return 0;
    }

    这里说明了什么,其实建立一个数组时,其实数组前的一个名字……其实它就是指针的意思,比如a[20]的a,其实它神似一个指针变量,叫做数组指针,当我把它的地址赋给p时,两者就没有任何区别。

    包括pa,虽然看起来只是将a[0]的值给了它,其实效果是和前面一样的,而且a[20]的一些地址都会存在pa和p里面,pa,p任然独立存在,里面的内容任然是地址。

    现在数组名字是一个比较屌的东西

    继续上面的实验,加几行代码。

        printf("%d
    ",sizeof(a));
        printf("%d
    ",sizeof(p));
        printf("%d
    ",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
    ",sizeof(c));
    }

    输出是4和80,数组作为形参到了函数里,就变成了一个指针。

    最后还有一个好玩的东西

    #include<stdio.h>
    int main()
    {
        int a=0;
        int* p=&a;
        printf ("%x
    ",&a);
        printf ("%x
    ",p); //前面两个是一样的
        printf ("%x
    ",p[0]);
        printf ("%x
    ",p[1]);
        printf ("%x
    ",p[2]);
        printf ("%x
    ",p[3]);
        printf ("%x
    ",p[4]);
    
        return 0;
    }

    居然可以输出!没有报错.而且p[0]的地址不是p与a.

    数据几乎没有什么规律,因为,printf,对于数组的输出,输出的实际上就是那个地址的值,所以这里非常相似!

    我又做了一个事

    #include<stdio.h>
    int main()
    {
        int a=0;
        int* p=&a;
        printf ("%x
    ",&a);
        printf ("%x
    ",p);
        printf ("%x
    ",&p[0]);
        printf ("%x
    ",&p[1]);
        printf ("%x
    ",&p[2]);
        printf ("%x
    ",&p[3]);
        printf ("%x
    ",&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]

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

  • 相关阅读:
    linux命令应用之一
    HIVE配置错误信息
    二分查找(JAVA)
    HBase1.0.1.1 API与原来有所不同
    hbase shell中log4j重复问题
    hadoop本地库无法加载
    利用mapreduce将数据从hdfs导入到hbase遇到的问题
    HBase伪分布式环境下,HBase的API操作,遇到的问题
    Hadoop开发中,如何开启、关闭控制台打印调试信息
    Hadoop的mapreduce开发过程,我遇到的错误集锦(持续更新)
  • 原文地址:https://www.cnblogs.com/zuoguangxing/p/3441628.html
Copyright © 2011-2022 走看看