C++指针相减(同类型)

来源:互联网 发布:淘宝公司人员架构 编辑:程序博客网 时间:2024/06/06 08:44

笔试时碰到一个题目:是关于指针相减的问题。当时不会,回来后编程实验一下,发现结果与我想的不同,令人费解。今天在网上看到了这篇文章,顿时茅塞顿开。

文章链接:http://blog.csdn.net/harvic880925/article/details/8953854

前言:本文是转载的,但由于转载地址仍然是转载的,所以不知原文出处,对此表示抱歉,但仍对原作者表示深深的敬意!!!谢谢!!

如果两个指针指向同一个数组,它们就可以相减,其结果为两个指针之间的元素数目。 

     假设我住在广场路124号,Mag住在广场路142号,每家之间的地址间距是2(在我这一侧用连续的偶数作为街道地址),那麽Mag家就在我家往前(142-124)/2家,也就是说可以得到我们两家之间相隔8家。 

     也就是说可以利用两个指向同一数组的指针相减得到两个指针之间元素的个数。 

     如果两个指针不是指向同一个数组,它们相减就没有意义了。 

     C本身无法防止非法的指针减法运算,它无法为你提出任何警告或提示。 

     指针相减的结果是某种整类型的值,为此,ANSI C标准<stddef.h>头文件中预定义了一个整类型ptrdiff_t。尽管在不同的编译程序中ptrdiff_t的类型可能各不相同,但它们都适当地定义了ptrdiff_t类型。 

     把指针强制转换成指向纯粹的内存地址的指针,通常就是转换成void*类型,但是在本例中将指针强制转换成char*类型,因为void*类型的指针之间不能进行减法运算。 

  1. #include <stdio.h>   
  2.   
  3. #include <stddef.h>   
  4.   
  5. struct stuff{ char name[16]; }   
  6.   
  7. struct stuff array[]={ {"The"}, {"quick"}, {"brown"}, {"fox"}, {"jumped"}, {"over"}, {"the"}, {"lazy"}, {"dog."}, {""} }  
  8.   
  9. main()  
  10.   
  11. {   
  12.   
  13.         struct stuff *p0= & array[0];  
  14.   
  15.         struct stuff *p8= & array[8];  
  16.   
  17.         int             * px =(int *) &array[8];  
  18.   
  19.   
  20.         ptrdiff_t diff=p8-p0;                                                        // 8  = ((int)p8 - (int) p0) / sizeof(stuff)         (被减者的指针类型决定)  
  21.   
  22.         ptrdiff_t diffx=px-p0;                                                      // 8  = ( (int)p8 - (int)p0) / sizeof(int)          (特殊的不同类型的指针相减时)  
  23.   
  24.         ptrdiff_t addr_diff=(char*)p8-(char*)p0;                        //128= ( (int)p8 - (int)p0) / sizeof(char)  
  25.   
  26.         ptrdiff_t addr_diffx=(char*)px-(char*)p0;                       //128= ( (int)p8 - (int)p0) / sizeof(char)         (特殊的不同类型的指针相减时)  
  27.   
  28.   
  29.         printf("&array[0]=p0=%P\n",(void*)p0);                           
  30.   
  31.         printf("&array[8]=p8=%P\n",(void*)p8);   
  32.   
  33.         printf("The difference of pointers is %ld\n",(long)diff);  
  34.   
  35.         printf("The difference of addresses is %ld\n",(long)addr_diff);   
  36.   
  37.         printf("p8-8=%P\n",(void*)(p8-8));  
  38.   
  39.         printf("p0+8=%P(same as p8)\n",(void*)(p0+8));  
  40.   
  41.        return 0;  
  42.   
  43. }   
  44. 本例演示了指针的减法运算。该例中有一个结构体数组,每个结构体的长度都是16字节。如果是对指向结构体数组的指针进行减法运算,则a[0]和a[8]之间的距离为8,如果将结构体数组的指针强制转换成指向纯粹的内存地址的指针之后再相减,则a[0]和a[8]之间的距离为128。如果将指向a[8]的指针减去8,该指针所指向的位置并不是往前移了8个字节,而是往前移了8个数组元素。

  45. 另一篇中的摘录:原文地址:http://blog.csdn.net/liu4584945/article/details/6191373

    指针相减的陷阱两个指针相减,结果并不是两个指针数值上的差,而是把这个差除以指针指向类型的大小的结果
    比如: WCHAR pA = 0x00400000, pB = 0x00401000, pB - pA的结果是0x1000 / sizeof(WCHAR) = 0x0800
    有时候,为了计算字符串的字节数,会采用这种手段。然后在MBCS编码时并没有刻意去考虑指针相减的问题,
    所以得出的结果不会去除以sizeof(TCHAR)。但是到了Unicode,这种编码显然就是有问题的,
    弄得不好就是内存泄漏。更何况这种错误因为不会在编译阶段报错,所以要发现变得极其困难

    在发现并修正后,唯一能做的也就是吸取教训,以后编码的时候多多注意这类问题了



0 0
原创粉丝点击