指针篇之三 一步有多远

    指针的算术运算不象普通变量增大和减小那么简单,它意味着对物理内存的偏移访问,一旦步子跨得不对,后果就是非法访问甚至crash。所以指针运算有严格限制:它只允许加上或减去一个整数,而不允许加减变量以及乘除法操作。并且指针加减运算和通常的整数加减有所不同,比如:

    char a[20];

    int *ptr=a; 

    ptr = ptr +1;

    注意,尽管后面被初始化指向字符数组a[20]的首地址,但int *ptr这一定义形式表明ptr指向的内存类型是int。以此为依据,对下一句ptr = ptr+1编译器是这样处理的把指针ptr的值加上1*sizeof(int)地址以字节为单位,sizeof(int)等于4字节,所以ptr指向的地址将由原来数组a首地址向高地址方向增加4字节。a[20]中每个char单元占1字节,所以ptr的指向从a[0]移到a[4]。再看

    char a[20];

    int *ptr=a;

    ptr+=6;

    这次对ptr6编译器做类似处理将指针ptr加上6*sizeof(int)=6*4=24字节,但如果ptr向高地址方向移动24字节,就指向了数组a的合法范围之外。这就是内存访问越界的错误,但语法上却可以编译通过。这两个例子充分体现了指针的灵活性与危险性。ptrn,处理基本一样,只是把ptr值减去n*sizeof(int),即ptr向低地址方向移动n*sizeof(int)个字节。

   总结:指针ptrold加上(减去)一个整数n,结果是一个新的指针ptrnewptrnewptrold指向相同的内存类型,ptrnew的值比ptrold的值增加(减少)n*sizeof(ptrold所指内存类型)个字节。即ptrnew指向的内存将比ptrold指向的内存向高(低)地址方向移动n*sizeof(ptrold所指内存类型)个字节。下面是一个常见面试题:

    short array[10]={0,1,2,3,4,5,6,7,8,9};

    int *pVal = array;

   ...

    pVal += 2;

    printf(“pVal =%d\n”,*(short* )pVal);

    结果是pVal = 4;

     同样是一步,姚明和潘长江绝对不一样。所以涉及指针算术运算时,一定要看这一步是以什么为单位,即反复重复的:要关注指针指向的内存类型,而不能和指针赋值对象的类型混淆。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值