指针(二)

来源:互联网 发布:淘宝如何入驻拼多多 编辑:程序博客网 时间:2024/06/07 10:53

一、数组指针的概念及定义

1.数组指针

    数组元素指针,每个变量都有地址,一个数组包含若干元素,每个数组元素都有相应的地址,指针变量可以指向数组元素(把某一元素的地址放到一个指针变量中),所谓数组元素的指针就是数组元素的地址,因为指针就是地址,可以用一个指针变量指向一个数组元素。

    我们这个数组指针其实就是一维数组与指针之间的关系。

    通过下图我们来分析一维数组与指针之间的关系。

如图所示,我们定义了一个int类型的一维数组a,并且定义了一个int类型的指针变量p,并且指针p指向数组a。

       这里有一个重要的数组特性:

       数组的首地址 = 数组名 = 数组第一个元素的地址

所以:p=a=&a[0]

        注意!

         1>数组名 a 不代表整个数组,只代表数组首元素的地址。

         2>“p=a”的作用是“把a数组的收元素的地址符给指针变量p”,而不是“把数组a各元素的值赋给p”。

         3>数组名a就是一个地址,是一个常量。


        总结:

        1)引用一个数组元素,可用下面两种方法:

                            >下标法,如a[i]形式

                            >指针法,如*(a+i)或*(p+i)

       2)数组名  a是常量,所以a++是错误的

          指针变量p是变量,所以P++是正确的

       3)数组指针——指向数组元素的指针

       4)数组指针的作用——使用数组指针间接访问数组的元素


      接下来我们用程序实例来说明“指针与一维数组之间的关系”

打印如下:

下面我们看看指针p是否指向数组?并且看看指向数组的什么位置?看看数组的地址是多少?

程序打印输出如下:

        小结:

                 从这个打印可以知道,指针p指向了数组并且指向了数组都地址也就是数组第一个元素的地址&shu[0]。


下面我们打印出数组每个元素的地址看看

打印如下:

从这个打印图我们可以知道:

       数组中每个元素都有自己的地址,因为指针是访问变量的地址,所以我们可以用指针来访问数组的每个元素。

下面,用指针访问数组中的值

打印如下:

         

        说明:

        前面我们已经验证了指针变量p是指向数组第一个元素的地址,即为p=0012FF34,所以如果要想访问第一、三个元素,那么就需要使得p分别指向第一个第三个元素的地址。由于数组的下标是从0开始的所以指针p指向的元素的下标是0,所以p+2就是指针第三个元素,(p+2)=0x0012FF3c,所以*(p+2)就是取第三个元素。


既然用指针可以访问数组元素,那么如何用指针来遍历数组

打印如下:

        说明:

        通过上面有关知识的说明我们知道,p指向数组的第一个元素,也就是下标为0的元素,所以p+i表示指向下标为i的元素,又因为加*表示取指针中的值。如*p表示,取p中的值,而*(p+i)表示取p+i中的值。所以通过for循环可以打印出数组中的元素。


下面看一个例子:

       要求:用指针来逆序数组

程序如下:

子函数一

子函数二


打印如下:

       这里写了两个子函数,子函数一的形参变量是一个形参数组而子函数二中的形参变量是一个指针变量,这两只方法都可以实现目标。

       子函数一可以实现的原因:

       把实参数组a的地址传给了形参数组arr,arr会以传来的地址为首地址开始向下取出数组中的元素赋给自己,所以在子函数中数组arr就相当于是数组a。但是在内存中子函数中进行的元素交换还是在数组a中进行的,所以说“arr会以传来的地址为首地址开始向下取出数组中的元素赋给自己”这样说是为了好理解。

     

       子函数二可以实现的原因:

       因为子函数中的形参是指针变量P,所示调用子函数时会把实参数组a的地址传给了指针变量p,也就是说指针p指向了数组a的内存空间。所以在子函数中做的一切命令,直接是在实参数组的内存空间中进行的。


下面的程序可以更好的反应了:数组名是一个地址、指针只接受地址

打印如下:

关于nX(&a[2],8)说明:

       &a[2]:表示把数组a的下标为2的地址传送给arr[ ]

       8       :这是因为我们的数组长度为10,如果从第二个地址开始访问,向下访问10个就会发生越界。越界是危险的!


下面打印一下越界现象来看看(一般禁止越界操作)   

      

打印如下:

 

总结:

         指针就是地址,指针是一个变量

         数组名也是个地址,数组名是一个常量


二、一维指针数组


1、一维指针数组


         一个数组的元素值为指针则这个数组是指针数组。指针数组是一组有序的指针的集合。指针数组的所有元素都必须是具有相同存储类型和指向相同数据类型的指针变量。

       指针数组的一般格式:

                     类型说明符 *数组名[数组长度]

      例如:

               int *pa[3]  表示pa是一个指针数组,它有三个数组元素,每个元素值都是一个指针,指向整形变量。

      小结1:

               指针是什么?指针就是地址

               一维指针数组就可以理解为:一个一维数组,数组中存储的变量时“地址”,这样的一维数组就是一维指针数组。

     小结2:

               指针变量与普通变量的区别、一维指针数组和一维普通数组的区别,他们最大的区别是指针变量和指针数组在定义的时候都有一个“*”,如果没有这个“ *  ”,那么就是普通变量或是普通数组。


下面有实例来说明一维指针数组的应用

打印如下:


先打印出变量a,b,c的地址,这是为了更好的便于我们观察和理解。

那么一维指针数组:p[3]={&a,&b,&c}

就变成了                  p[3]={0012FF44,0012FF40,0012FF3C}


       一维指针数组和普通的一维数组是不同的,因为一维指针数组中存储的是地址,尽管如此我们还是把一维指针数组看做是普通数组开操作。


       下面我们打印一下一维指针数组的元素看看:

打印如下:

下面用一维指针数组名来访问数组中的元素

打印如下:

下面我们在程序中加一个 一维普通数组来做参照:

打印如下:

从现在来看还是没有什么太大的区别


打印如下:


打印变量a,b,c的值

打印如下:



       通过上面的打印我们可以知道:

       到现在为止我们可以把一维指针数组当成普通的一维数组

       1>数组名[数子]表示数组中存储的元素,同样我们在一维指针数组中做这样的操作也是取数组中存储的元素。

       2>*(数组名+数子)这也是表示取数组中的元素,同样我们在一维指针数组中做这样的操作也是取数组中存储的元素。

所以到目前为止来说  普通一维数组 和 一维指针数组 是没有什么区别,只是数组中存储的内容不而已,普通一维数组中存储的是 值;一维指针数组存储的是 地址。

       3>正因为这些差别,在取a,b,c的值得时候,一维指针数组要再*一次,当然这是针对用数组名来取值得情况下:

       第一次*的时候是为了取一维指针数组中元素(*p=0012FF44),由于这时的元素还是一个地址所以还需要取一次,取地址0012FF44中的内容,故*(*p)=*(0012FF44)=4


       所以: 一维指针数组 可以当做普通数组来分析!








0 0
原创粉丝点击