指针算术运算

C/C++中可以对指针进行进行算术运算,但其如何解释呢? 有如下的程序:

#include <stdio.h>

int main()
{
 int* a = reinterpret_cast<int*>(0x100);
 a+=4;
 printf("a = %p/n",a);

 double* b = reinterpret_cast<double*>(0x200);
 b+=4;
 printf("b = %p/n",b);

 return 0;
}

 

运行后输出如下:

 

a=00000110

b=00000220

 

也就是说a+=4,被解释为a+= 4*sizeof(int),同样b+=4 被解释为b+=4*sizeof(double),

那么是不是说对于如下的定义:

A* B = C; B(+/-)D可以解释为 B(+/-)D*sizeof(A)呢? 且看下面的程序:

 

#include <stdio.h>

int main()
{
 int* a = reinterpret_cast<int*>(0x100);
 int* b = reinterpret_cast<int*>(0x200);
 a+=b;
 printf("a+=b = %p/n",a);

 double* c = reinterpret_cast<double*>(0x200);
 double* d = reinterpret_cast<double*>(0x300);
 c+=d;
 printf("c+=d = %p/n",c);

 return 0;
}

 

试图编译却出现如下错误:

error C2297: '+=' : illegal, right operand has type 'int *'
error C2114: '+=' : pointer on left; needs integral value on right

 

这是说两个指针之间不能直接相加了。那么两个指针直接相减可以么? 答案也是否定的。

int main()
{
 int* a = reinterpret_cast<int*>(0x100);
 int* b = reinterpret_cast<int*>(0x50);
 a-=b;
 printf("a-=b = %p/n",a);

 double* c = reinterpret_cast<double*>(0x200);
 double* d = reinterpret_cast<double*>(0x150);
 c-=d;
 printf("c-=d = %p/n",c);

 return 0;
}

error C2297: '-=' : illegal, right operand has type 'int *'
error C2114: '-=' : pointer on left; needs integral value on right

 

同样指针之间相乘,相除可以么?结果也是否定的。

 

这是为什么呢?其实指针用于指向一块内存,那么唯一有意义的操作就是前后偏移游历这块内存了,

而偏移的单位是sizeof(指针基础类型)。指针加上获取减去一个整形量N,其实相当于游历指向的这块内存,

也就是相对于内存基地址而作的偏移,偏移量为N*sizeof(指针基础类型)。显然合法的运算就是指针加减

一个整形量,所以而两个指针之间这种运算,指针乘除整形量或者两个指针乘除都是无法编译通过的,

这是内部指针类型的运算符的限制。

 

 有了上面的结论,我们再看下面的代码:

在一个数组a中,a[n]表示第n个元素本身,那么&a[n]就是第n个元素的地址了。

#include <stdio.h>

int main()
{
 int a[6] = {1,2,3,4,5,6};
    printf("a=%p/n",a);
 printf("a[2]=%p/n",&a[2]);

 return 0;
}

 

输出如下:

a=0012ff4c

&a[2]=0012ff54

从数据元素是连续存储的角度出发,上述结果完全正确:(0012ff54-0012ff4c) = 8 也就是

说前面有2个int元素了。下面又有这么个程序,

#include <stdio.h>

int main()
{
 int a[6] = {1,2,3,4,5,6};
 printf("%d/n",a[&a[3]-&a[1]]);


 return 0;
}

 

它能编译通过么? 按照上面的两个指针不能直接相加减的说法,应该是编译不过了,但事实

是它可以编译过,而且运行结果为3!  这似乎存在了一个矛盾了!&a[3],&a[1] 也是两个

指针啊,为什么他们可以相加减呢? 错!这里偷换了一个概念:指针和地址,虽然指针存储

一块内存的起始地址,但地址不一定就是指针

但上面的运行结果为3,也就表明了&a[3]-&a[1] = 2, 这是怎么得到的呢,很显然是(&a[3]-&a[1])/4

这似乎说明了地址也是有大小的。从某种意义上来说指针算术运算只是地址算术运算的一种特殊形式,

有自己更为严格的限制。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值