概述
前言:本文是转载的,但由于转载地址仍然是转载的,所以不知原文出处,对此表示抱歉,但仍对原作者表示深深的敬意!!!谢谢!!
如果两个指针指向同一个数组,它们就可以相减,其结果为两个指针之间的元素数目。
也就是说可以利用两个指向同一数组的指针相减得到两个指针之间元素的个数。
如果两个指针不是指向同一个数组,它们相减就没有意义了。
C本身无法防止非法的指针减法运算,它无法为你提出任何警告或提示。
指针相减的结果是某种整类型的值,为此,ANSI C标准<stddef.h>头文件中预定义了一个整类型ptrdiff_t。尽管在不同的编译程序中ptrdiff_t的类型可能各不相同,但它们都适当地定义了 ptrdiff_t类型。
把指针强制转换成指向纯粹的内存地址的指针,通常就是转换成void*类型,但是在本例中将指针强制转换成char*类型,因为void*类型的指针之间不能进行减法运算。
#include <stdio.h>
#include <stddef.h>
struct stuff{ char name[16]; }
struct stuff array[]={ {"The"}, {"quick"}, {"brown"}, {"fox"}, {"jumped"}, {"over"}, {"the"}, {"lazy"}, {"dog."}, {""} }
main()
{
struct stuff *p0= & array[0];
struct stuff *p8= & array[8];
int * px =(int *) &array[8];
ptrdiff_t diff=p8-p0; // 8 = ((int)p8 - (int) p0) / sizeof(stuff) (被减者的指针类型决定)
ptrdiff_t diffx=px-p0; // 8 = ( (int)p8 - (int)p0) / sizeof(int) (特殊的不同类型的指针相减时)
ptrdiff_t addr_diff=(char*)p8-(char*)p0; //128= ( (int)p8 - (int)p0) / sizeof(char)
ptrdiff_t addr_diffx=(char*)px-(char*)p0; //128= ( (int)p8 - (int)p0) / sizeof(char) (特殊的不同类型的指针相减时)
printf("&array[0]=p0=%Pn",(void*)p0);
printf("&array[8]=p8=%Pn",(void*)p8);
printf("The difference of pointers is %ldn",(long)diff);
printf("The difference of addresses is %ldn",(long)addr_diff);
printf("p8-8=%Pn",(void*)(p8-8));
printf("p0+8=%P(same as p8)n",(void*)(p0+8));
return 0;
}
本例演示了指针的减法运算。该例中有一个结构体数组,每个结构体的长度都是16字节。如果是对指向结构体数组的指针进行减法运算,则a[0]和a[8]之间的距离为8,如果将结构体数组的指针强制转换成指向纯粹的内存地址的指针之后再相减,则a[0]和a[8]之间的距离为128。如果将指向a[8]的指针减去8,该指针所指向的位置并不是往前移了8个字节,而是往前移了8个数组元素。
另一篇中的摘录:原文地址:http://blog.csdn.net/liu4584945/article/details/6191373
指针相减的陷阱两个指针相减,结果并不是两个指针数值上的差,而是把这个差除以指针指向类型的大小的结果。
比如: WCHAR pA = 0x00400000, pB = 0x00401000, pB - pA的结果是0x1000 / sizeof(WCHAR) = 0x0800
有时候,为了计算字符串的字节数,会采用这种手段。然后在MBCS编码时并没有刻意去考虑指针相减的问题,
所以得出的结果不会去除以sizeof(TCHAR)。但是到了Unicode,这种编码显然就是有问题的,
弄得不好就是内存泄漏。更何况这种错误因为不会在编译阶段报错,所以要发现变得极其困难。
在发现并修正后,唯一能做的也就是吸取教训,以后编码的时候多多注意这类问题了
最后
以上就是忧郁哈密瓜为你收集整理的指针相减(同类型与不同类型)的全部内容,希望文章能够帮你解决指针相减(同类型与不同类型)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复