指向指针C++ 指针 (3)-算术运算

题记:写这篇博客要主是加深自己对指向指针的认识和总结实现算法时的一些验经和训教,如果有错误请指出,万分感谢。

    指针可以加上或减去一个整数。指针的这种运算的意义和平日的数值的加减运算的意义是不一样的,以字节为单位。

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)++;//单元的值+1
 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<stdio.h>
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所指向的类型)个字节。

     

    指针和指针停止加减:

    两个指针不能停止加法运算,这是非法操纵,因为停止加法后,失掉的结果指向一个不知所向的地方,而且毫无意义。两个指针可以停止减法操纵,但必须类型雷同,一般用在数组方面,未几说了。

文章结束给大家分享下程序员的一些笑话语录: AdobeFlash拖垮Windows拖垮IE!又拖垮Linux拖垮Ubuntu拖垮FirxEox!还拖垮BSD拖垮MacOS拖垮Safri!简直无所不拖!AdobeFlash滚出网路世界!不要以为市占有率高就可以持续出烂货产品!以后替代品多得是!

--------------------------------- 原创文章 By
指向和指针
---------------------------------

posted @ 2013-05-30 20:54  xinyuyuanm  阅读(296)  评论(0编辑  收藏  举报