C Primer Plus 第10章 数组和指针 10.5 指针操做

C提供了6种基本的指针操做,下面的程序将具体演示这些操做。为了显示每个操做的结果,程序将打印出指针的值(即指针指向的地址)、指针指向地址中存储的内容,以及指针自己的地址(若是您的编译器不支持%p说明符,那么想要打印出地址,就须要使用%u或者%lu)。数组

程序清单10.13示例了可对指针8种基本操做。除了这些操做,你还能够使用关系运算符来比较指针。函数

程序清单10.13  ptr_ops.c程序指针

//ptr_ops.c指针操做
#include <stdio.h>
int main(void)
{
    int urn[5]={100,200,300,400,500};
    int * ptr1,* ptr2,* ptr3;

    ptr1 = urn;  //把一个地址赋给指针
    ptr2 = &urn[2];  //同上
                     //取得指针指向的值,而且获得指针的地址
    printf("pointer value, dereferenced pointer, pointer address:\n");
    printf("ptr1 = %p,*ptr1 = %d,&ptr1 = %p\n",
           ptr1,*ptr1,&ptr1);
    //指针加法
    ptr3 = ptr1 + 4;
    printf("\nadding an int to a pointer:\n");
    printf("ptr1 + 4 = %p, *(ptr1+3)=%d\n",
           ptr1+4,*(ptr1+3));
    //递增指针
    ptr1++;
    printf("\nvalues after ptr1++\n");
    printf("ptr1 = %p,*ptr1 = %d,&ptr1 = %p\n",
           ptr1,*ptr1,&ptr1);
    //递减指针
    ptr2--;
    printf("\nvalues after ptr2--\n");
    printf("ptr2 = %p,*ptr2 = %d,&ptr2 = %p\n",
           ptr2,*ptr2,&ptr2);
    //恢复为初始值
    --ptr1;
    ++ptr2;
    printf("\npointers reset to original values:\n");
    printf("ptr1 = %p,ptr2 = %p\n",
           ptr1,ptr2);
    //一个指针减去另外一个指针
    printf("\nsubtracting one pointer from another:\n");
    printf("ptr2 = %p, ptr1 = %p,ptr2 - ptr1 = %d\n",
           ptr2,ptr1,ptr2-ptr1);
    //一个指针减去一个整数
    printf("\nsubtracting an int from a pointer:\n");
    printf("ptr3 = %p, ptr3 - 2 = %p\n",
           ptr3,ptr3 - 2);
    return 0;
}

下面的列表描述了可对指针变量执行的基本操做:code

** 赋值(assignment)---能够把一个地址赋给指针。一般使用数组名或地址运算符&来进行赋值。注意:地址应该和指针类型兼容。也就是说,不能把一个double类型的地址赋给一个指向int的指针。内存

** 求值(value - finding)或取值(dereferencing)---运算符*可取出指针指向地址中存储的数值。所以,*ptr1开始为100,即存储在地址0x0012ff38中的值。ci

** 取指针地址---指针变量同其余变量同样具备地址和数值,使用运算符&能够获得存储指针自己的地址。本例中,ptr1被存储在内存地址ox0012ff34中。该内存单元的内容是0x0012ff38,即urn的地址。编译器

** 将一个整数加给指针---能够使用+运算符来把一个整数加给一个指针,或者把一个指针加给一个正数。两种状况下,这个整数都会和指针所指类型的字节数相乘,而后所得结果会加到初始地址上。因而ptr1+4的结果就等同于&urn[4]。若是相加的结果超出了初始指针所指向数组的范围,那么这个结果是不肯定的,除非超出数组最后一个元素的地址可以确保是有效的。io

** 增长指针的值 ---能够经过通常的加法或增量运算符来增长一个指针的值对指向某数组元素的指针作增量运算,可让指针指向数组的下一个元素。所以,ptr1++运算把ptr1加上数值4(咱们系统上int为4个字节),使ptr1指向urn[1]。如今ptr1的值是0x0012ff3c,*ptr1的数值为200。请注意ptr1自己的地址仍然是0x0012ff34。别忘了,变量是不会由于它的值的变化而移动位置的编译

** 从指针中减去一个整数 ---能够使用-运算符来从一个指针中减去一个整数指针必须是第一个操做数,或者是一个指向整数的指针这个整数都会和指针所指类型的字节相乘,而后所获得的结果会从初始地址中减掉。因而,ptr3-2的结果等同于&urn[2],由于ptr3是指向&urn[4]的。若是相减结果超出了初始指针所指向的数组范围,那么这个结果是不肯定的,除非超出数组最后一个元素的地址可以确保有效。class

** 减少指针的值---指针固然也能够作减量运算。请注意,你能够使用前缀或后缀形式的增量和减量运算符。

** 求差值(Differencing)---能够求出两个指针以前的差值。一般对分别指向同一个数组内的两个元素的指针求差值,以求出元素之间的距离差值的单位是相应类型的大小有效指针差值运算的前提是参加运算的两个指针是指向同一个数组(或是其中之一指向数组后面的第一个地址)。

** 比较---能够使用关系运算符来比较两个指针的值,前提是两个指针具备相同的类型

注意,这里有两种形式的减法。能够用一个指针减掉另外一个指针获得一个整数,也能够从一个指针中减掉一个整数获得一个指针

在进行指针的增量和减量运算时,要牢记一些注意事项。计算机并不检查指针是否仍然指向某个数组元素。C保证指向数组元素的指针和指向数组后的第一个地址的指针都是有效的。

另外,能够对指向一个数组元素的指针进行取值运算。但不能对指向数组后的第一个地址的指针进行取值运算,尽管这样的指针是合法的

特别注意:不能对未初始化的指针取值

切记:当建立一个指针时,系统只分配了用来存储指针自己的内存空间,并不分配有来存储数据的内存空间。所以在使用指针以前,必须给它赋予一个已分配的内存地址。好比,能够把一个已存在的变量地址赋给指针。

指针的最初功能在于同函数交换信息。从前面所学的内容可知,若是须要让被调函数修改调用函数中的变量,就必须使用指针。

指针的另外一个基本功能是用在处理数组的函数中。

相关文章
相关标签/搜索