Logo Background RSS

[C/C++]指针详解(2) — 指针运算与运算符

  • 本文由 SUNJIANSUNJIAN 于 2008年十一月19日 发表在 《C/C++
    交流信息: 哇!现在有 8 位大侠指点过了.8 条评论 Comments (117 views)

    接《[C/C++]指针详解(1) — 复杂数据类型与指针

    一、指针的算术运算
    指针可以加上或减去一个整数。指针的这种运算的意义和通常的数值的加减运算的意义是不一样的,以单元为单位。例如:
    例二:
    char a[20];
    int *ptr=(int *)a; //
    强制类型转换并不会改变a 的类型
    ptr++;

    在上例中,指针ptr 的类型是int*,它指向的类型是int,它被初始化为指向整型变量a。接下来的第3 句中,指针ptr 被加了1,编译器是这样处理的:它把指针ptr 的值加上了sizeof(int),在32 位程序中,是被加上了4,因为在32 位程序中,int 占4 个字节。由于地址是用字节做单位的,故ptr 所指向的地址由原来的变量a 的地址向高地址方向增加了4 个字节。由于char 类型的长度是一个字节,所以,原来ptr 是指向数组a 的第0 号元开始的四个字节,此时指向了数组a 中从第4 号单元开始的四个字节。我们可以用一个指针和一个循环来遍历一个数组,看例子:
    例三:
    int array[20]={0};
    int *ptr=array;
    for(i=0;i<20;i++)
    {
    (*ptr)++;
    ptr++;
    }

    这个例子将整型数组中各个单元的值加1。由于每次循环都将指针ptr加1 个单元,所以每次循环都能访问数组的下一个单元。
    再看例子:
    例四:
    char a[20]=”You_are_a_girl”;
    int *ptr=(int *)a;
    ptr+=5;

    在这个例子中,ptr 被加上了5,编译器是这样处理的:将指针ptr 的值加上5 乘sizeof(int),在32 位程序中就是加上了5 乘4=20。由于地址的单位是字节,故现在的ptr 所指向的地址比起加5 后的ptr 所指向的地址来说,向高地址方向移动了20 个字节。在这个例子中,没加5 前的ptr 指向数组a 的第0 号单元开始的四个字节,加5 后,ptr 已经指向了数组a 的
    合法范围之外了。虽然这种情况在应用上会出问题,但在语法上却是可以的。这也体现出了指针的灵活性。如果上例中,ptr 是被减去5,那么处理过程大同小异,只不过ptr 的值是被减去5 乘sizeof(int),新的ptr 指向的地址将比原来的ptr 所指向的地址向低地址方向移动了20 个字节。
    下面请允许我再举一个例子:(一个误区)
    例五:
    #include


    int main()
    {
    char a[20]=” You_are_a_girl”;
    char *p=a;
    char **ptr=&p;
    //printf(”p=%d\n”,p);
    //printf(”ptr=%d\n”,ptr);
    //printf(”*ptr=%d\n”,*ptr);
    printf(”**ptr=%c\n”,**ptr);
    ptr++;
    //printf(”ptr=%d\n”,ptr);
    //printf(”*ptr=%d\n”,*ptr);
    printf(”**ptr=%c\n”,**ptr);
    }

    误区一、输出答案为Y 和o
    误解:ptr 是一个char 的二级指针,当执行ptr++;时,会使指针加一个sizeof(char),所以输出如上结果,这个可能只是少部分人的结果.

    误区二、输出答案为Y 和a
    误解:ptr 指向的是一个char *类型,当执行ptr++;时,会使指针加一个sizeof(char *)(有可能会有人认为这个值为1,那就会得到误区一的答案,这个值应该是4,参考前面内容), 即&p+4; 那进行一次取值运算不就指向数组中的第五个元素了吗?那输出的结果不就是数组中第五个元素了吗?答案是否定的.正解: ptr 的类型是char **,指向的类型是一个char *类型,该指向的
    地址就是p的地址(&p),当执行ptr++;时,会使指针加一个sizeof(char*),即&p+4;那*(&p+4)指向哪呢,这个你去问上帝吧,或者他会告诉你在哪?所以最后的输出会是一个随机的值,或许是一个非法操作.
    总结一下:
    一个指针ptrold 加(减)一个整数n 后,结果是一个新的指针ptrnew,ptrnew 的类型和ptrold 的类型相同,ptrnew 所指向的类型和ptrold所指向的类型也相同。ptrnew 的值将比ptrold 的值增加(减少)了n 乘sizeof(ptrold 所指向的类型)个字节。就是说,ptrnew 所指向的内存区将比ptrold 所指向的内存区向高(低)地址方向移动了n 乘sizeof(ptrold 所指向的类型)个字节。

    指针和指针进行加减:
    两个指针不能进行加法运算,这是非法操作,因为进行加法后,得到的结果指向一个不知所向的地方,而且毫无意义。两个指针可以进行减法操作,但必须类型相同,一般用在数组方面,不多说了。

    二、取地址运算符&和间接运算符*
    这里&是取地址运算符,*是间接运算符。&a 的运算结果是一个指针,指针的类型是a 的类型加个*,指针所指向的类型是a 的类型,指针所指向的地址嘛,那就是a 的地址。*p 的运算结果就五花八门了。总之*p 的结果是p 所指向的东西,这个东西有这些特点:它的类型是p 指向的类型,它所占用的地址是p所指向的地址。

    例六:
    int a=12; int b; int *p; int **ptr;
    p=&a; //&a 的结果是一个指针,类型是int*,指向的类型是
    //int,指向的地址是a 的地址。
    *p=24; //*p 的结果,在这里它的类型是int,它所占用的地址是
    //p 所指向的地址,显然,*p 就是变量a。
    ptr=&p; //&p 的结果是个指针,该指针的类型是p 的类型加个*,
    //在这里是int **。该指针所指向的类型是p 的类型,这
    //里是int*。该指针所指向的地址就是指针p 自己的地址。
    *ptr=&b; //*ptr 是个指针,&b 的结果也是个指针,且这两个指针
    //的类型和所指向的类型是一样的,所以用&b 来给*ptr 赋
    //值就是毫无问题的了。
    **ptr=34; //*ptr 的结果是ptr 所指向的东西,在这里是一个指针,
    //对这个指针再做一次*运算,结果是一个int 类型的变量。

  • 我们的说明!

    欢迎转载,但请您以链接形式注明本文出处和本站原文链接,下面是链接形式,谢谢合作!
    出处链接:Allove of Paradise
    原文链接:http://blog.allove.org/archives/pointer-operator.html
8 条评论
  1. #1 Yacca
    十一月 19th, 2008 at 2:56 下午

    竟然让我装gear…厄 目前这个破机子是没办法了

    [回复]

    Daniel Reply:

    哇 我正想问问大家 我安了 WP Turbo 和 WP Super Cahche , 速度上有不有稍微快点的感觉呢?

    [回复]

    Yacca Reply:

    @Daniel, 加载速度还可以的 你放心吧

    [回复]

    Daniel Reply:

    @Yacca, 你是说现在啊,我都没有那个了,中文支持不好

    [回复]

    Post ReplyPost Reply
  2. #2 醉倚西风
    十一月 19th, 2008 at 4:56 下午

    又是技术文章

    [回复]

    Post ReplyPost Reply
  3. #3 老所
    十一月 19th, 2008 at 11:11 下午

    这些文章,没用C写过一些程序是很枯燥的。

    [回复]

    Daniel Reply:

    @老所, 写过就知道其中也是很多乐趣与奥妙的了 哈哈

    [回复]

    Post ReplyPost Reply
  4. #4 sanding
    十二月 1st, 2008 at 12:54 下午

    C/C++ JAVA 全才,赞~~~

    [回复]

    Post ReplyPost Reply
Leave a Comment

ALLOVE短信